为什么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...
相关推荐
LeeAt6 分钟前
手搓一个 Ollama 本地 SSE 全栈聊天助手
前端
全_6 分钟前
全栈项目实践五:抽离npm包
前端
dorisrv7 分钟前
使用requestIdleCallback和requestAnimationFrame优化前端性能
前端
dorisrv7 分钟前
CSS Grid + Flexbox响应式复杂布局实现
前端
前端灵派派7 分钟前
openlayer选择移动图标
前端
重铸码农荣光7 分钟前
深入理解 JavaScript 继承:从原型链到 call/apply 的灵活运用
前端·javascript·面试
禅思院7 分钟前
vite项目hmr热更新问题
前端·vue.js·架构
dorisrv10 分钟前
TRAE SOLO 正式版:AI全链路开发的新范式 🚀
前端·trae
小明记账簿_微信小程序11 分钟前
antd v3 select自定义下拉框内容失去焦点时会关闭下拉框
前端
前端老宋Running11 分钟前
告别“祖传”defineProperty!Vue 3 靠 Proxy 练就了什么“神功”?
前端·vue.js·面试