vertical-align
最后更新 2026-11-02
- vertical-align
- 基线
- 行盒
- inline-block
- 图片底部
- baseline
- middle
本页目录
vertical-align 的名字起得很糟:它让人以为能“垂直对齐任何东西”,实际上它只对行内元素与表格单元格起作用,而且参照的是基线,不是容器的中心。
给一个块级 div 写 vertical-align: middle 什么也不会发生——这是最常见的误用。
只管行内元素
生效的对象:
- 行内元素(
inline); - 行内块(
inline-block)与替换元素(图片、<video>、<input>); - 表格单元格(
td/th)——这是另一套语义,本文不展开。
不生效的:块级元素、flex / grid 的子项(那些用 align-items / align-self)。
所以判断它有没有用,先看目标是不是“一行里的小东西”。
取值
| 值 | 含义 |
|---|---|
baseline |
默认。元素自己的基线对齐到父级行盒的基线 |
middle |
元素的中线对齐到“基线 + x 高度的一半” |
text-top / text-bottom |
对齐到父级内容区的顶 / 底 |
top / bottom |
对齐到行盒的顶 / 底 |
sub / super |
下移 / 上移一点(具体偏移由浏览器与字体决定) |
<length> |
相对基线上下移动(正数向上) |
<percentage> |
相对 line-height 的百分比移动 |
top / bottom 与 text-top / text-bottom 的区别经常被忽略:前者看行盒(包含行高撑出来的空白),后者看内容区(字体上下伸围出的那块)。行高很大时,两者差得很远。
基线在哪,由谁决定
行盒的基线不是一个固定高度的线,而是由参与这一行的内容算出来的:
- 有文字时,取文字所在字体的基线;
- 只有
inline-block时,取它内部最后一个行盒的基线; - 如果
inline-block里没有内容(或overflow不是visible),它的基线就是底边。
最后一条是很多“莫名其妙的偏移”的来源。
middle 不是垂直居中
middle 的定义是“元素的垂直中点对齐父级基线 + 半个 x 高度”。它让图标与文字看起来对齐,但不是让元素在容器里居中。
想在容器里垂直居中:用 flex(align-items: center)或 grid。这也是为什么现代布局里 vertical-align 基本只用来做行内对齐。
图片底部那道缝
最经典的坑:
<div><img src="photo.jpg" alt=""></div>
图片下方会出现几像素的空白。原因:<img> 是行内替换元素,默认 vertical-align: baseline,它坐在基线上——而基线下方还留着降部空间(给 g、p 的尾巴)。
三种消法:
img { display: block; } /* 最干脆,图片不再参与行内排版 */
img { vertical-align: top; } /* 或者 middle / bottom */
div { line-height: 0; } /* 或者把行高归零(小心影响其它内容) */
推荐 display: block:图片本来就不是文字,别让它参与行盒。
在本站怎么试
下面两个方块是 inline-block,默认坐在基线上。换选项看它们相对文字移动:
注意选项里写的是 .box { … } 这种完整规则:vertical-align 要作用在方块上,而不是外层那个 div。
本站的排版预览为什么没有这一项
一期的排版预览只渲染一整块文本,里面没有行内元素,vertical-align 无从作用——所以当时故意没做(见 docs/roadmap.md §5)。
要用到它的地方(图标与文字对齐、图片与说明文字对齐),本来也不该在排版测试里调,而是在组件里写死。
延伸阅读
- MDN:
vertical-align - CSS Inline Layout 规范:行盒、基线与
vertical-align - 本站:line-height、合成与杂项