line-boxes模型
行内级元素(包括display属性为inline和inline-block的元素)会相互挨着排成行。如果一行排不下,就会在下方再建一行。
每一行的内容都会被装在一个行盒子(line-boxes)中,内容的高度不同,行盒子的高度也不同。在行盒子内部,可以通过vertical-align来对齐个别元素。
行内盒子(inline boxes):行盒子中的内容,比如<span>, <a>
都是行内盒子,光秃秃的文字也是行内盒子,属于匿名inline boxes。
行盒子(line boxes): 由一个一个的行内盒子组成。行盒子的高度是该行内各个元素在垂直方向上对齐完之后撑开的最大高度。
内容区(content area):围绕文字看不见的box,其大小与font-size和font-family有关,其高度可以认为鼠标选中文字时背景色的高度(后面解释)。
以代码为例:
<head>
<style>
.container {
font-size: 30px;
background-color: gray;
}
.inner {
background: blue;
}
</style>
</head>
<body>
<div class="container">
X匿名文本X
<img
src="https://5b0988e595225.cdn.sohucs.com/images/20190126/49805ed0acda405fbdd3440e47f437d4.jpeg"
alt=""
width="200"
height="200"
/>
<span class="inner">Xspan中的文本X</span>
</div>
</body>
具体如下图:可以看出行盒子的高度是内部三个行内盒子对齐摆放后的高度。
基线
不同类型元素的基线确定
参考:
张鑫旭系列博客
《CSS float浮动的深入研究、详解及拓展(一)》
https://www.jianshu.com/p/c165c7619e38
https://www.zhangxinxu.com/wordpress/2015/08/css-deep-understand-vertical-align-and-line-height/comment-page-1/
对于标准内联元素( 无论是否有内容 )和匿名内联元素( 文字 ),都是完全遵守基线定义的,即以英文字母x的下端沿作为基线。
具体来说:
对于inline-block元素来说:基线是正常流中最后一个line boxes的基线, 如果这个line box里面既没有line boxes或者本身’overflow’属性的计算值不是’visible’, 这种情况下基线是margin底边缘。
以 img 为代表的替换元素:其基线是 margin 的下边线;类似的还有 iframe、canvas、video、textarea 等。
以 input 为代表的替换元素:其基线是元素里面文字的基线( 字母 x 下边线 ),类似的还有 select 等。
行盒子(line-boxes)的基线:行盒子的基线是个变量。也就是说,基线画在哪里需要满足很多条件,比如要符合vertical-align指定的条件,同时还要保证行盒子高度最小。因为行盒子的基线并不可见,所以有时候不容易确定它的位置。但实际上有个简单的办法可以令其可见。只要在相关行的开头加上一个字母,比如上图中开头的“x”即可。如果这个字母没有被设置对齐,那么它默认就位于基线之上。
基线&中线&绝对中心线的概念
参考:https://www.cnblogs.com/Yuzili/p/7260590.html
在上图的匿名内联元素:
基线指小写x字母的下边缘线。
顶线指中文汉字的顶部位置。
底线指中文汉字的底部位置。
中线 指基线 往上1/2的位置,也就是小写x字母的中间交叉点那个位置。(注意中线不是绝对中心线,因为x有点下沉,没有在内容区中垂直居中)
内容区 指的是底线和顶线包裹的区域。
x-height指小写x的高度。
行高指的是相邻文本行基线间的距离
行距是指行高减去字体高度的距离,上图中顶线的上部空白和底线的下部空白是半行距。
设置font-size为0
如果设置font-size为0,那么此时内容区高度是0,各种线都在高度为0的这条线上,绝对中心线和中线就会重合。
先介绍几个例子
vertical-align的不同属性的效果
分析:
(1)baseline对齐:使元素的基线与父元素的基线对齐
- 行盒子的基线就是该行中匿名文字x的下边缘。
- 匿名的文本inline-box的基线在小写x的下边缘,img的inline-box的基线是图片下边缘,span的inline-box的基线是x的下边缘。
- 默认的对齐方式是baseline对齐,所有的行内盒子的基线都与行盒子的基线对齐。
(2)middle对齐:使元素的中部与父元素的基线加上父元素 x-height的一半对齐。
middle的含义:Aligns the middle of the element with the baseline plus half the x-height of the parent.),也就是将图片的中点与行盒子的中线(x的交叉点)对齐。
接下来设置图片的对齐方式为middle,含义是将图片的中间与行盒子的中线对齐。
(3)sub对齐:使元素的基线与父元素的下标基线对齐。
(4) text-top对齐:使元素的顶部与父元素的顶部对齐。
(5)top对齐:使元素及其后代元素的顶部与整行的顶部对齐。
实现图片的垂直居中
<style>
.p1 {
font-size: 80px;
line-height: 240px;
background-color: gray;
}
img {
vertical-align: middle;
}
</style>
<body>
<p class="p1">
<img id="img1" src="OIP.jpg" alt="">
</p>
</body>
由于行盒子的中线和绝对中心位置不在同一处。所以给图片设置vertical-align为middle,图片没有居中。
可以将font-size设置为0,中线和绝对中心位置就会重合,图片就会垂直居中了。
<style>
.p1 {
font-size: 0; /**/
line-height: 240px;
background-color: gray;
}
img {
vertical-align: middle;
}
</style>
<body>
<p class="p1">
<img id="img1" src="OIP.jpg" alt="">
</p>
</body>
行高line-height
The line-height CSS property sets the height of a line box. It’s commonly used to set the distance between lines of text. On block-level elements, it specifies the minimum height of line boxes within the element. On non-replaced inline elements, it specifies the height that is used to calculate line box height.
line-height CSS 属性用于设置多行元素的空间量,如多行文本的间距。对于块级元素,它指定元素行盒(line boxes)的最小高度(一个没有设置height
属性的div
的高度就是由一个一个line boxes
的高度堆积而成的)。对于非替代的 inline 元素,它用于计算行盒(line box)的高度。
<head>
<style>
.test1 {
font-size: 20px;
line-height: 0;
border: 1px solid red;
background: green;
}
.test2 {
font-size: 0;
line-height: 20px;
border: 1px solid orange;
background: yellow;
}
</style>
</head>
<body>
<div class="test1">测试1</div>
<div style="height: 40px; border: 1px solid gray;"></div>
<div class="test2">测试2</div>
</body>
对于非替换元素的纯内联元素,其可视高度完全由line-height决定。对于文本这样的纯内联元素,line-height就是高度计算的基石,用专业说法就是指定了用来计算行框盒子高度的基础高度。
对于纯文本元素,line-height直接决定了最终的高度。但是,如果同时有替换元素,则line-height只能决定最小高度。
对于块级元素,line-height对其本身是没有任何作用的,我们平时改变块级元素的line-height,块级元素的高度跟着变化实际上是通过改变块级元素里面内联级别元素占据的高度实现的。
无论内联元素line-height如何设置,最终父级元素的高度都是由数值大的那个line-height决定的。
内联元素的高度由固定高度和不固定高度组成,这个不固定的部分就是这里的“行距”。换句话说,line-height之所以起作用,就是通过改变“行距”来实现的。在CSS中,“行距”分散在当前文字的上方和下方,也就是即使是第一行文字,其上方也是有“行距”的,只不过这个“行距”的高度仅仅是完整“行距”高度的一半,因此,也被称为“半行距”。
行距 = line-height
- font-size
line-height的默认值是normal(Depends on the user agent. Desktop browsers (including Firefox) use a default value of roughly 1.2, depending on the element’s font-family.),还支持无单位数字、百分比值以及长度值。为无单位数字时,该属性的应用值是这个无单位数字乘以该元素的字体大小;为百分比值时,与元素自身的字体大小有关,计算值是给定的百分比值乘以元素计算出的字体大小。推荐在设置 line-height 时使用无单位数值
可以使用font-size
间接控制,比方font-size
设为0
, line-height
值也改为0了。
只要有“内联盒子”在,就一定会有“行框盒子”,就是每一行内联元素外面包裹的一层看不见的盒子。然后,重点来了,在每个“行框盒子”前面有一个宽度为0的具有该元素的字体和行高属性的看不见的“幽灵空白节点”。
设置了line-height的行框line-box,具有的特性:
垂直居中性:line-height是通过line-box行框体现的,而行框包括文本+文本顶部空白区域+文本底部空白区域,文本顶部和文本底部是line-height 与 font-size差值的一半,所以,line-box与文本共用中基线,这就是行高的垂直居中性。一般来说中基线在x的交叉点偏上一点(垂直中心是字符content area的中心,而对于字符x
而言,都是比绝对中心位置要下沉的(不同字体下沉幅度不一样),换句更易懂的描述就是x
的中心位置都是在字符内容区域高度中心点的下方)。换句更简单的话说就是:middle中线位置(字符x
的中心)并不是字符内容的绝对居中位置。