ホームページ > 記事 > ウェブフロントエンド > CSS は、vertical-align と line-height_html/css_WEB-ITnose の関係を深く理解しています。
ここ数週間記事を書いていませんでした。とても忙しくてかゆいです。長い記事を書いていませんでした。数カ月、私はとても忙しくてあなたがいなくて寂しいです、四半期の半分は記事でそれについて話していませんでした、私はそれについて本当に考えたくてうずうずしています。
後ろの建物でカップルが喧嘩していました。声は大きくて力強く、このような態度は小さな町だけだと思いました。突然、私が上海郊外の小さな田舎町に住んでいることを思い出しました。
私は JD.com の株を数十株購入しました。このゲームをプレイするのは初めてです。JD.com の発展に期待しています。本当は株価が21円の時に買う予定だったのですが、為替送金の際に労働時間が必要であることを思い出しました。そしたら忙しくて忘れてたけど、今買ったらもう20%以上増えてた、石鹸って人を幸せにするんだよ。これを書いているときに、思わず携帯を取り出して見てみました。おっと、子供に粉ミルクを半分入れるのに十分なお金ができました。
ソープといえば「監獄学園」のココを思い出しますね~
ソープとゲイ友達の伝説は第11地区にも広がっていることが判明。それだけでなく、2 次元に加えて、コード次元も彼らに深く愛されています。たとえば、CSS のvertical-align と line-height は、表面的には非常に異なっているように見えますが、実際には良い関係にある典型的な例です。裏庭に入ってきた腰の折れた人たち!
はい、とても血まみれです!
田舎の人は嘘をつきません。それでは、垂直方向の整列と行の高さの間のとんでもない同性愛者の関係についてゴシップしましょう!
ご存知のとおり、vertical-align はフットボール チームを形成するのに十分な多くの属性値をサポートしています。 >
その中に、vertical-align と line-height の密接な関係を明らかにする属性値があります。それはどの属性値だと思いますか?/* 关键字值 */vertical-align: baseline;vertical-align: sub;vertical-align: super;vertical-align: text-top;vertical-align: text-bottom;vertical-align: middle;vertical-align: top;vertical-align: bottom;/* <长度> 值 */vertical-align: 10em;vertical-align: 4px;/* <百分比> 值 */vertical-align: 10%;/* 全局值 */vertical-align: inherit;vertical-align: initial;vertical-align: unset;
わぁ、すごいですね!実は一目見て誰もが認識したのが「パーセント値」なのです。
vertical-align のパーセント値は、フォント サイズやその他の属性を基準として計算されるのではなく、行の高さを基準として計算されます。簡単な例を挙げると、次の CSS コード:
実際には、次と同等です:
{ line-height: 30px; vertical-align: -10%;}
CSS プロパティは非常に多くありますが、それらは行に関連しています。 -高さ、それは真実ではありません。
{ line-height: 30px; vertical-align: -3px; /* = 30px * -10% */ }
//zxx: IE6/IE7 ブラウザーでの垂直方向の整列のパーセント値は、10 進数の行の高さをサポートしていません
3. 舞台裏で広く見られる同性愛者の関係
、vertical-align と line-height の地下関係は HTML5 ドキュメント宣言から始まります。 したがって、以下で説明する現象はすべて、ページが HTML5 として宣言されているという前提に基づいています。次の doctype と同様です:
さらに、以下の効果の多くは実際のデモであるため、以下のコンテンツを表示するには最新のブラウザを使用してください。一部の動作が説明と一致せず、ブラウザが正常である場合は、元のソースにアクセスしていないことが原因である可能性があります。<!doctype html><html>
① 基本現象
のような
<div><img src="mm1.jpg"></div>
タグがあり、その中に
画像があるとします。以下のようになります:
<div style="background-color:#e5edff;"><img src="mm1.jpg"></div>そうですね、見た目は普通で、すべてが自然です。ただし、この dc6dce4a544fdca2df29d5ac0ea9906b 要素に水色などの背景色を追加すると、次のようになります:
写真の下に空白があります:
誰もが同じような問題に遭遇したことがあると思います。なぜ写真の下に空白があるのか考えたことがあるでしょうか。
実際、この空白のギャップは、vertical-align と line-height が連動することで発生します。
まず、全員がこれに注意する必要があります。インライン要素の場合、vertical-align と line-height は目に見えませんが、実際には「どこにでも」存在します。
したがって、インライン要素の理解できる、または想像できないさまざまな動作については、基本的に、vertical-align と line-height を使用して動作を説明し、修正することができます。ただし、それでも多くの時間がかかります。したがって、他では見ることができない以下の内容を 30 分かけてじっくり読んでください。
② Ghost Blank Node
1. 感情的認知、2. 具体的な思考 の 2 つの側面から始めます。
例如,我称vertical-align和line-height为好基友(包括以前称浮动和绝对定位是兄弟),就是“情感化认知”;而这里的「幽灵空白节点」就是“具象化思维”。
那「幽灵空白节点」是个什么意思呢?
在HTML5文档声明下,块状元素内部的内联元素的行为表现,就好像块状元素内部还有一个(更有可能两个-前后)看不见摸不着没有宽度没有实体的空白节点,这个假想又似乎存在的空白节点,我称之为“幽灵空白节点”。//zxx: 自己捣腾的概念,不是权威,欢迎其他小伙伴反馈权威解释
抽象了这个概念,绝对定位与text-align的一些行为表现,以及这里的行为表现,就好理解了。
还是上面的图片下边缘留空隙的例子,实际上,这种行为表现,就跟图片前面或者后面有一个宽度为0的空格元素表现是一致的。但是,空格是透明的,为了便于大家理解,我就直接使用很明显的匿名inline box, 也就是字符代替。如下,大家会发现,图片下面的间隙,依旧是那个间隙。
zxx
下面要解释这个间隙就好解释了。下面,我们让新增的文本inline-block化,然后弄个白色背景,显示其占据的高度。
zxx
会发现,图片下面的间隙,依旧是那个间隙。但是,我们的理解就好理解了。回答下面几个问题,我们就知道表现的原因了:
vertical-align默认的对齐方式是?
后面zxx文字的高度从何而来?
上面2个问题就很简单了:
vertical-align默认值是baseline, 也就是基线对齐。而基线是什么,基线就是字母X的下边缘(参见“ 字母’x’在CSS世界中的角色和故事 ”一文)。所以,妹子图片的下边缘就和后面zxx中的字母x下边缘对齐(见下图)。而字符zxx本身是有高度的,对吧,于是,图片下面就留空了。
而zxx文字的高度是由行高决定的。
因此,简单的图片下面留白行为表现,本质上,就是vertical-align和line-height背地里搞基造成的。
知道了问题的原因,我们就可以对症下药,准确搞定图片下面我们不希望看到的间隙。怎么搞呢?一对基友,vertical-align和line-height我们随便搞定一个就可以了。
比方说vertical-align.
图片默认是inline水平的,而vertical-align对块状水平的元素无感。因此,我们只要让图片display水平为block就可以了,我们可以直接设置display或者浮动、绝对定位等(如果布局允许)。例如:
img { display: block; }
则妹子就会变这样:
下面的空隙不见了。
告别baseline, 取用其他属性值,比方说bottom/middle/top都是可以的。
vertical-align:bottom vertical-align:middle vertical-align:top
zxx
下面的空隙高度,实际上是文字计算后的行高值和字母x下边缘的距离。因此,只要行高足够小,实际文字占据的高度的底部就会在x的上面,下面没有了高度区域支撑,自然,图片就会有容器底边贴合在一起了。比方说,我们设置行高5像素:
div { line-height: 5px; }
zxx
如果line-height是相对单位,例如line-height:1.6或者line-height:160%之类,也可以使用font-size间接控制,比方说来个狠的,font-size设为大鸡蛋0, 本质上还是改变line-height值.
div { font-size: 0; }
zxx
由于「幽灵空白节点」的存在,因此,我们可以进一步衍生,实现其他更实用的效果,比方说任意尺寸的图片(或者内联块状化的多行文字)的垂直居中效果。就是借助本文的两位男主角,vertical-align和line-height。
你想啊,图片后面(前面)有个类似空格字符的节点,然后就能响应line-height形成高度,此时,图片再来个vertical-align:middle,当当当当,就可以和这个被行高撑高的「幽灵空白节点」(近似)垂直对齐了。
例如:
div { line-height: 240px; }img { vertical-align: middle; }
然后就会这样子:
不过上面的效果并不是完全的垂直居中,只是近似(稍微仔细看可以看出来)。为什么只是近似呢?那是因为「幽灵空白节点」还是默认的基线对齐。因此,实际上,此时的效果是图片的中线对齐后面幽灵字符的基线。
嘛嘛,单纯的文字还是太苍白了,截个图示意下吧:
因此,要想完全垂直居中,最先想到的方法就是让后面的“幽灵字符”也是vertical-align:middle,然而,呵呵,既然称之为“幽灵”就表示不会受非继承特性的属性影响,所以,根本没法设置vertical-align:middle,除非你自己创建一个显示的内联元素。
我们就没有办法了吗?当然不是,“幽灵字符”可以受具有继承特性的CSS属性影响,于是,我们可以通过其他东西来做调整,让字符的基线和中线在一起,或者说在一个位置上就可以了。有人可能要疑问了,这能行吗?啊,是可以的。
对于字符而言,基线的定义是什么?是字符x的下边缘,而中线的定义是什么,是基线往上1/2字符x的高度,于是,我们就可以列个公式,已知:x = x - 1/2 * x, 求x? 显然,x就是0,于是,我们只要让字符x的肉眼视觉高度为0就可以了。怎么搞?很简单,font-size:0, 于是,完全垂直居中就是:
div { line-height: 240px; font-size: 0; }img { vertical-align: middle; }
结果是:
处女座的你,是不是看过去舒服多啦!?
这种通过line-height定高,元素vertical-align:middle垂直居中的方法不仅适用于现代浏览器,连IE7浏览器也是支持的:
不过和其他浏览器再使用上还是有些需要注意的地方,就是,HTML不能这样:
<div><img src="mm1.jpg"></div>
而是需要在图片标签结束处留下空格后者换行:
<div><img src="mm1.jpg"><!-- 这里要折行或空格 --></div>
多年前曾分享过“ text-align:justify下列表的两端对齐布局 ”的技术,其中,为了让任意个数的列表最后一行也是对齐排列,在列表最后会辅助列表等宽的空标签元素来占位,类似下面红色高亮HTML代码:
.justify-fix { display: inline-block; width: 128px; }
<div style="text-align: justify;"><img src="img/mm1.jpg" width="128"><img src="img/mm1.jpg" width="128"><img src="img/mm1.jpg" width="128"><img src="img/mm1.jpg" width="128"><i class="justify-fix"></i><i class="justify-fix"></i><i class="justify-fix"></i></div>
.justify-fix { display: inline-block; width: 128px; }.outline .justify-fix { outline: 1px dashed red; }
为了节约空间,我就使用小图示意:
同样的,在白色背景下,似乎看上去效果还不赖,但是,如果给div容器加个背景色~~
会惊讶的发现,下面多了很大一块间隙(如下截图):
为了便于大家看其究竟,我把占位i元素outline高亮下,于是,效果如下:
结果会发现,上面巨大的空隙是由占位i元素上面和下面的间隙共同组成的。
下面问题来了:上面的间隙是如何产生的?下面的间隙是如何产生的?如果去除这些间隙呢?
很多时候,复杂问题是由简单问题组合而成的,实际上,这里的间隙现象的始作俑者和上面的简单现象一样,都是vertical-align和line-height搞基带来的不好的影响。
按照之前问题解决方法,我们可以直接来个line-height:0解决垂直间隙问题:
div { line-height: 0; }
结果图片和图片之间的间隙是没有了,但是,图片和最后的占位元素之间依然有个几像素的间距, ,啊啊啊啊,这究竟是什么鬼?
简单现象的背后往往有大的学问,接下来是本文的高潮了,究其原因,要说到inline-block元素和基线baseline之间的一些纠缠的关系。
CSS2的可视化格式模型文档中有一么一段话:
The baseline of an ‘inline-block’ is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its ‘overflow’ property has a computed value other than ‘visible’, in which case the baseline is the bottom margin edge.
英文看得眼睛大,于是我中文直译了下:
‘inline-block’的基线是正常流中最后一个line box的基线, 除非,这个line box里面既没有line boxes或者本身’overflow’属性的计算值而不是’visible’, 这种情况下基线是margin底边缘。
这段文档中出现了很多专有名词line box, line boxes等,这些是内联盒子模型中的概念,是CSS进阶必备知识。我在“ 浮动深入理解(一) ”一文的中间穿插介绍了该模型。//zxx: 我现在后悔了,内联盒子模型当初应该直接独立成一篇文章,这样其他文章可以很干净地引用,所谓文章的模块化书写
如果大家没有足够精力去学习之,可以先看下面这张图:
由于上面的译文是直译的,理解起来还是有些拗口,我使用通俗的话描述就是: 一个inline-block元素,如果里面没有inline内联元素,或者overflow不是visible,则该元素的基线就是其margin底边缘,否则,其基线就是元素里面最后一行内联元素的基线。
纳尼,还是没反应过来?
那我们看下面这个例子,应该就知道什么意思了。
两个同尺寸的inline-block水平元素,唯一区别就是一个空的,一个里面有字符,代码如下:
.dib-baseline { display: inline-block; width: 150px; height: 150px; border: 1px solid #cad5eb; background-color: #f0f3f9;}
<span class="dib-baseline"></span><span class="dib-baseline">x-baseline</span>
.dib-baseline { display: inline-block; width: 100px; height: 100px; border: 1px solid #cad5eb; background-color: #f0f3f9; }
结果,科科:
x-baseline
会发现,明明尺寸、display水平都是一样的,结果呢,两个却不在一个水平线上对齐,为什么呢?哈哈,上面的规范已经说明了一切。第一个框框里面没有内联元素,因此,基线就是容器的margin下边缘,也就是下边框下面的位置;而第二个框框里面有字符,纯正的内联元素,因此,第二个框框就是这些字符的基线,也就是字母x的下边缘了。于是,我们就看到了框框1下边缘和框框2里面字符x底边对齐的好戏。框框2有个小彩蛋,点击可以toggle其innerHTML,会发现,如果框框2里面没文字,就和框框1举案齐眉了。
下面我们要做一件很有必要的事情,用来帮助我们理解上面复杂例子在line-height值为0后的表现,什么事情呢?哈,同境界模拟,我们也设置框框2的line-height值为0,于是,就会是下面这样的表现:
x-baseline
知道框框2为何又下沉了一点吗?
因为字符实际占据的高度是由行高决定的,当行高变成0的时候,字符占据的高度也是0,此时,高度的起始位置就变成了字符content area的垂直中心位置,于是,文字就一半落在看看2的外面了。
由于文字字符上移了,自然基线位置(字母x的底边缘)也往上移动了,于是,两个框框的垂直落差就更大了。
OK,明白了上面的简单例子,也就能明白上面的复杂例子。紧接着,如果我们在最后一个占位的5a8028ccc7a7e27417bff9f05adf5932元素后面新增同样的x-baseline字符,则:
x-baseline
大家是不是就可以明白原因所在啦!
额~居然还有小伙伴皱眉头,那我再用文字解释下:
现在行高line-height是0, 则最后的x-baseline的垂直中线就和上面一列的图片对齐,而基线呢,就在中线下面差不多半个x的高度地方,而这个高度落差就是最后图片和容器的间隙高度值,因为前面的439978f6ffe922c695ac74a058f90131是个空元素,基线是自身的底部,哈哈,造业啊!
OK,一旦知道了现象的本质,我们就能轻松对症下药了!要么改造占位5a8028ccc7a7e27417bff9f05adf5932元素的基线、要么改造“幽灵空白节点”的基线位置、要么使用其他vertical-align对齐方式~
首先,来个最有意思的方法,对吧, 改造占位5a8028ccc7a7e27417bff9f05adf5932元素的基线 。这个很简单,对吧,只要在空的5a8028ccc7a7e27417bff9f05adf5932元素里面随便放几个字符就可以了,例如,里面有个x:
xx-baseline
会发现,间隙没有了! 为什么呢?哈哈,因为5a8028ccc7a7e27417bff9f05adf5932元素的基线和“幽灵空白节点”的基线位置现在一致了,没有了错位,自然就不会有间隙啦!
改造“幽灵空白节点”的基线位置,哈哈,使用font-size,字体足够小时,基线和中线会重合在一起,什么时候字体足够小呢,就是0. 于是,CSS代码(line-height如果是相对值,line-height:0也可以省掉):
div { font-size: 0; }
使用其他vertical-align对齐方式,就是让两端对齐的列表元素vertical-align:top/bottom/...之类。
div { line-height: 0; }.justify-fix { display: inline-block; width: 128px; vertical-align: top; }
最后的效果是:
恩恩,各种方法都完美解决了垂直间隙的问题,来,各个大大的赞!
至此,vertical-align和line-height的断背基友关系算是彻底暴露了,而且,从行为表现上来看,line-height是攻,vertical-align是个受。而很多内联元素的行为表现,就是这对基友搞七搞八一起搞出来的。
以前,关系处于地下的时候,我们可能不会明白,为何男厕所的卷纸用得比女厕所还快;但是,现在关系暴露了,很多以前我们想不明白的事情一下子就豁然开朗了。
したがって、私たちはこれらの友人たちを正しい態度で見なければなりません。結局のところ、この 2 人は CSS において非常に重要な主役となり得るのです。
この記事には多くの知識ポイントが含まれており、リファクタリングの分野で成功したい場合は、多くの基本的かつ詳細な内容を理解する必要があることをお勧めします。スペースが限られているので、vertical-align の各値の標準的な説明や、インライン ボックス モデルなど、質問があれば自分で検索して調べることができます。あらゆる形式のコミュニケーションも歓迎します。
この記事はご存知のとおり、週末に夜更かしして書いたもので、今は以前と同じではなく、まぶたが水銀で満たされているように感じます。記事内の表現や書き込みに間違いがある場合は修正を歓迎します。
読んでいただきありがとうございます。素晴らしい週末をお過ごしください! 400メートルリレーでの中国チームの銀メダル獲得もおめでとうございます。
var funImgVt = function(input) { var imgvt = document.getElementById("imgVt");if(imgvt) { imgvt.style.verticalAlign=input.value; };
この記事は、スクリプトの動作やスタイルの制御を含むオリジナルの記事であり、ナレッジポイントは頻繁に更新され、いくつかの誤りは修正されます。そのため、再印刷する場合は、古い知識や誤った知識による誤解を避けるために、元のソースを保持してください。より良い読書体験を。
この記事のアドレス: http://www.zhangxinxu.com/wordpress/?p=4925
(この記事はここまで)