为什么line-height不生效?看不见的幽灵空白节点?

1.情景再现

在调整css统一规范的时候发现一个问题,先贴代码:

js 复制代码
 <div class="item">
    <div class="flex-div">sssss</div>
    <span class="desc">hhhhhh</span>
  </div>
  
 <style scoped>
.item {
  line-height: 32px;
}
.flex-div {
  display: flex;
  align-items: center;
  flex-direction: column;
  background-color: gray;
}
.desc {
  display: inline-block;
  line-height: 18px;
  background: red;
}
</style>

这一段代码的意思是用一个line-height:32px的外层div包裹了一个flex布局的div和一个span标签。

此外还根据具体的业务需求对flex和span标签进行了样式改造。

但是很容易就发现好像span标签中的line-height:18px没有生效,图中sss和hhh之间明显有一段空白,乍一看line-height还是32px,没被18px覆盖。

2.问题定位及原因分析

经过f12审查元素后发现sssss行高确实为32px,hhhhh行高也为修改后的18px。但为什么会出现一块空白呢?

知识点引入
  • 基线

字母 x 的下边缘(线)就是基线

在 CSS 中有两个重要属性,line-heightvertical-align都与基线有关,line-height行高的定义就是两个基线之间的距离,vertical-align的默认值就baseline,也就是基线对齐。对于内联元素而言,虽然vertical-alignline-height看不见,但实际上到处都是

  • 幽灵空白节点

在 HTML5 规范中有这样一句话:

"Each line box starts with a zero-width inline box with the element's font and line height properties. We call that imaginary box a 'strut'."

每个行框盒子都以一个具有元素的字体和行高属性的零宽度行内框开始。我们称这个假想的盒子为"支柱"。
HTML5 文档声明 中,内联元素的所有解析和渲染表现就如同每个行框盒子的前面有一个"空白节点"一样。这个"空白节点"永远透明,不占据任何宽度,看不见也无法通过脚本获取,就好像幽灵一样,但又确确实实地存在,表现如同文本节点一样,因此,在张鑫旭大佬的《CSS 世界》一书中根据特点,将其称之为"幽灵空白节点",也就是官方规范中的"strut"。

  • line-boxes

在 line box 模型中,inline boxes的高度直接受line-height控制,而真正的高度表现则是由每行众多的inline boxes(等于内部最高的inline box的高度),而这些line boxes的高度垂直堆叠形成了containing box的高度,也就是我们见到的<p>或者<div>标签的高度。

根据以上知识点抛出一些个人猜想:

  • 对于内联元素,vertical-align的默认值是baseline,也就是基线对齐,所以<div>span中的元素都是以下边缘对齐。对于行内文本,每个框盒子有一个默认的基线对齐。而行高正是由基线到基线之间的距离来计算的。
  • 在上述代码中,.item 容器的行高被设置为 32px,而 <span> 标签的文本框的基线与 .item 容器的基线之间有一个距离差。这种差异会导致幽灵空白节点的计算结果与基线之间出现空隙。这个空隙在页面上会被呈现为两段之间的额外垂直距离。

3.解决办法

  1. vertical-align失效:vertical-align属性对于块级元素是无感的,因此我们只需要为元素设置dispalyblock即可;
  2. 修改vertical-align属性值为:top,修改其默认值baseline值为其他属性值,使其不再相对基线对齐;
  3. 修改line-height的值:上面我们说过line-height的定义是两基线之间的距离,因此在上面例子中,两段之间空隙实际上是"幽灵空白节点"计算后的行高值和基线的距离,因此,只要line-height足够小,便可以消除空隙。(注意这里是要在div上设置line-heght,然后让divinline boxes继承line-height属性)

修改后:

4.参考来源

  1. 带你探索神秘的"幽灵空白节点" zhuanlan.zhihu.com/p/391118319
  2. CSS中的幽灵空白节点 blog.csdn.net/zz132685708...
相关推荐
吃瓜群众i34 分钟前
理解Javascript闭包
前端·javascript
安大桃子37 分钟前
Mapbox GL + Deck.gl 三维实战:Mapbox 加载 Tileset3D 倾斜摄影模型
前端·webgl
yede41 分钟前
多行文本省略号显示,更多按钮展开全部
前端
就是我43 分钟前
React 应用性能优化实战
前端·react.js·性能优化
G扇子1 小时前
深入解析XSS攻击:从原理到防御的全方位指南
前端·安全
snakeshe10101 小时前
入解析React性能优化策略:eagerState的工作原理
前端
六边形6661 小时前
Vue中的 ref、toRef 和 toRefs 有什么区别
前端·vue.js·面试
kovli1 小时前
红宝书第十八讲:详解JavaScript的async/await与错误处理
前端·javascript
前端付豪1 小时前
🚀 React 应用国际化实战:深入掌握 react-i18next 的高级用法
前端·react.js·架构
代码小学僧1 小时前
使用 Cloudflare workers 做一个定时发送消息的飞书机器人
前端·云原生·serverless