案发
1.这些文字是如何摆放这么整齐的?为什么这个庞然大物的底部能对齐,顶部没对齐?为什么第二行与第一行的间距那么大?
2.为什么光秃秃的p标签没有高度,为什么在p标签中写入文字就有高度了呢?真的是因为文字大小撑起来的吗?
取证
vertical-align
是主谋之一,使得庞然大物的底部对齐line-height
是另一主谋,导致顶部没对齐以及巨大间距和p高度匿名文本
、em框
,font-size
,内容区
,行间距
,行内框
,行框
,行内非替换元素
间接或直接参与了犯罪
分析
场景回顾
<body style="padding:0 400px;border:1px solid #000">
<p style="font-size:16px;line-height:16px;">
This is the content of the element p. Here is inline element. I am glad that you come to read here.I hope that
<strong style="font-size:40px;">you</strong> can learn more from here. So just code, it's a great things. Let's go!!!.
</p>
</body>
身份鉴定
匿名文本:英文名
anonymous text
。简单来说就是所有未包含在行内元素中的字符串
。比如说案发现场的This is the......I hope that
em框:别名
字符框
(character box
)。em框在字体中定义。em框在css中不可见,是一个比较抽象的概念。这里只需要知道font-size
确定了各个em框
高度即可font-size:字体大小,与
em框
有关内容区:在
行内非替换元素
中,内容区是元素中各个字符的em框
串在一起构成的框。在行内替换元素
中,内容区是元素的固有高度再加上可能有的外边距、边框和内边框。行间距:
line-height
与font-size
之差,这个差分为两半,分别应用到内容区
的顶部和底部。行间距只适用于行内非替换元素
。行内框:这个框通过向内容区增加行间距来描述。对于
非替换元素
,元素行内框的高度刚好等于line-height的值。对于替换元素
,元素行内框的高度恰好等于内容区的高度,因为行间距。行框:这是包含该行中出现的行内框的
最高点
和最低点
的最小框。换句话说,行框的上边界要位于最高行内框的上边界,而行框的底边要放在最低行内框的下边界。-
非替换元素:如果元素的内容包含在文档中,则称之为非替换元素。比如说
<p>Inner content</p>或<div>Inner content</div>
-
替换元素:用作为其他内容占位符的一个元素。比如说
<img src="test.gif" />或者<input type="radio" />
重要提示:为了便于接下来的分析过程,请先了解他们的身份,然后带着疑问去参与分析。
模拟作案
首先是字体创建,该过程伴随着em框的生成,这个框是不可见的。开发人员无法控制该框大小。
每一个字符的产生都代表em框的生成。(那么这些字符是如何摆放的?为什么是浏览器呈现给我们的样式?人们写字的时候总是不经意间会写歪,那么浏览器又是如何做到对齐)
所有字符都全部action后,em框连在一起形成了
内容区
。这个区域依然不可见,很抽象。开发者无法直接控制,只能通过font-size间接影响em框从而影响内容区的大小。大多数情况下可以认为font-size大小即为内容区大小。内容区生成后,行内框也即将生成。这个时候,行间距吵闹着要把自己分成两半,一半放在内容区的头上,另一半下放在内容的底部,这样才显得恩爱嘛。
当爱情发生后总会产生些什么。于是行内框就诞生了,内容区和行间距的完美组合就是行内框。行内框是可见的。
所有的行内框都出生后,就得按照一定的规则制造一个包容它们的容器了,这就是行框。既然要包含它们,那必然得照顾最高和最矮的那个了。
以上是一般案例的发生,图解如下
代码如下:
<body style="padding:0 400px;border:1px solid #000">
<p style="font-size:16px;line-height:16px;background:#af3;border:1px solid red">
This is the content of the element p. Here is inline element. I am glad that you come to read here.I hope that
<strong style="background:yellow;">you can learn more from here</strong> . So just <span style="background:blue">code, it's a great things. Let's go!!!.</span>
</p>
</body>
黄色
和蓝色
区域代表内容区(在这同时也表示行内框),但
如果line-height与font-size大小不一时,使用background添加颜色时,作用的是内容区(content)。
温馨提示:思考时可以先考虑这一行中有哪些元素,再参照上述过程进行模拟。
案件实战
有了以上的基础后,这里便开始对两个案件合并进行透彻的剖析(因为问题牵扯的本质是一样的)。
代码重温:
<body style="padding:0 400px;border:1px solid #000">
<p style="font-size:16px;line-height:16px;">
This is the content of the element p. Here is inline element. I am glad that you come to read here.I hope that
<strong style="font-size:40px;">you</strong> can learn more from here. So just code, it's a great things. Let's go!!!.
</p>
</body>
效果重温:
问题重温:匿名文本和strong标签的内容是如何对齐的?line-height都是16px,第二行的间距还是那么大?
问题解决:首先是对齐的问题,关于行内元素的对齐就不得不提到vertical-align属性
浏览器代理(userAgentStylesheet
)给所有行内元素vertical-align的属性默认设置成了baseline。baseline这个属性值要求元素的基线与父元素的基线对齐。
这张图特意放大了
图中红色区域就是基线。css规范中对基线是否有明确规定?这一点我不太清楚。这里讲下个人的理解吧,基线是字符的特有属性,在字体被设计时就被确定好的。开发者无法控制。
由于userAgentStylesheet
默认vertical-align属性值为baseline
,所以它们就工整的对齐了。
第二个问题,第二行间距为什么如此大?
line-height明明都是16px。
原因很简单,line-height在应用到块级元素
时,它定义的是元素中
文本基线之间
的最小距离
。也就是说这不是一个固定死的数值,只是一个最低要求。
首先p标签是块级元素,其次line-height设置的大小与匿名文本的font-size一样,这导致内容区与行内框大小一致。然而对于strong标签里的文本来说,由于行内框小于内容区的大小,且行内框在内容区垂直居中
。
颜色强调
首先,每行的行框顶端
是紧靠着上一行行框的底端
。正如图中所见,着色区域
都是内容区
。因为前三行的font-size和line-height大小一致,所以行框即是着色区。但是第四行的内容区并不等于行框大小。
单独审视第四行,这里有两个匿名行内框(hope that 和can learn more)和一个行内元素strong。一共三个行内框,其中匿名行内框的大小等于font-size,而strong标签的行内框却远小于内容区的大小(font-size),由于行间距是对半上下分布的(参考案件模拟里的第四条),所以此时行内框的位置是在内容区是垂直居中的。
strong元素行内框
按照行框的生成过程(案件模拟)来看,这里行框的顶端是由strong元素的行内框顶端确定,底端则是有匿名文本的行内框的底端确定。
图中箭头所指即为行高。
至此,已经解决了对齐和为什么第二行间距如此大的问题。
当p标签中没有任何内容时,p的高度为0.当p中随意写入文本时,p会生成一个高度。这并不是被文本撑起来的,而是行框、行内框的作用。注意,通常情况下line-height有个默认值1.2。
这里就不细讲了,可以当做思考题,希望对各位有帮助。
我的第一次给了segmentFault。。。呜呜
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。