奇怪的行高

奇怪的行高

问题点

我们先想想这段代码的浏览器渲染效果是什么样?

1
2
3
4
5
6
7
<!-- 页面骨架 -->
<div class="test">
<span class="size-style">sphinx</span>
</div>
<div class="test1">
<span class="size-style1">sphinx</span>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 页面样式 */
.test {
font-family: simsun;
line-height: 40px;
background-color: yellow;
display: inline-block;
}
.size-style {
font-size: 31px;
background-color: white;
}

.test1 {
font-family: simsun; //宋体,字体显示区域大小与字体大小一致
line-height: 40px;
font-size: 31px;
background-color: yellow;
display: inline-block;
}
.size-style1 {
background-color: white;
}

粗看这段代码是两个一模一样的行内块级元素并排,因为 CSS font-size 属性的继承性,内部只有一个子元素,属性值写在子或父元素全部一致。理论渲染的效果也应该是一样。

理论效果.png

  • test 与 test1 的高度为 40px (行高)

但是实际浏览器渲染的结果如下图所示

实际效果.png

  • test1 元素高度 44px
  • test 元素高度 40px (行高)

这多出来来的4px高度是撒?

看渲染效果 test 和 test1 大体相似上半行距和字体显示局域是一样的,区别在于下半行距,test 多出的 4px就在这个区域。我们可以猜测是 test 内的 span 下方多出一个块级元素或换行的行内元素还有同行的行内元素(无宽度)。

  1. 我们先试试改变行高这个 4px 差的差距会跟随变化吗。(有变化=>但是从数值看不会是元素下方的)
  2. 删除 test 上的 line-height 属性。(发现 line-height 的默认值不会产生这个 4px 的误差)
  3. 查询 line-height 的默认值,是相对量。尝试使用其他相对量。(发现相对量不会产生 4px 误差;只有绝对量才会产生)。
  4. 尝试改变 font-size 的值(发现 4px 大小发生变化;额外元素能响应 font-size,但是想不出那个元素符合)。
  5. 好难看不出这是个撒,google了下发现每个 line-box 的起始位置都有一个宽度为 0 的字符(CSS 文档将其称为 strut),并将其纳入 line-box 的高度的计算中。

下面我们来验证下这个看不见的字符

前提:

  • 行内元素默认对齐是根据字符的基线
  • font-size的大小不等于实际看见的字符大小(content area)
  • 同一个 size 不同字体看见的字符大小也不一样,具体跟字体自己的规定相关(注:simsun 宋体 字符大小和font-size一致)
1
2
3
4
5
6
<div class="test">
<span class="size-style2">x</span>
</div>
<div class="test">
<span class="size-style">sphinx</span>
</div>
1
2
3
.size-style2 {
background-color: white; //其他属性继承自父元素,模拟幽灵元素
}

snipaste_20200229_172517.png

可以发现x字符由于字体和字号的不一样,字符占据的空间 + 字间距对比会有下沉。如果用一个元素包裹 x 和 test1 元素就会渲染出 test1 的样式。test1 中幽灵元素没造成影响是因为幽灵元素继承了父元素的字体字号与中属性一致​。​

问题解决

可以发现只要控制幽灵元素和其上下间距的范围不超出想实现效果的范围即可

方案:

  • 减小幽灵元素的字体大小(推荐,比较彻底直接设置0)
  • 减小幽灵元素的行高大小

参考:

You forgot to set the qrcode for Alipay. Please set it in _config.yml.
You forgot to set the qrcode for Wechat. Please set it in _config.yml.
You forgot to set the business and currency_code for Paypal. Please set it in _config.yml.
You forgot to set the url Patreon. Please set it in _config.yml.
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×