使用 CSS 为文本、图像和表格实现垂直节奏
摘要
本文探讨了在网页设计中使用 CSS 实现垂直节奏,特别是利用 `rlh` 单位进行文本对齐,并提供了一种 JavaScript 变通方案,以便响应式图像保持一致的间距。
<p><a href="https://lobste.rs/s/bvqio4/css_vertical_rhythm_for_text_images">评论</a></p>
查看缓存全文
缓存时间: 2026/05/12 07:42
# CSS 与文本、图片和表格的垂直节奏
来源:https://vincent.bernat.ch/en/blog/2026-css-vertical-rhythm
## Vincent Bernat 2026年4月22日
垂直节奏将页面上下排列的文本行对齐到一致的间距节奏上。它为眼睛的跟随创造了一种可预测的流动感。得益于 `rlh` CSS 单位,现在为文本实现垂直节奏变得更加容易。1 (https://vincent.bernat.ch/en/blog/2026-css-vertical-rhythm#sidenote-pawel) 但是,插图和表格可能会破坏布局。我内心那位业余排版专家希望遵循 Bringhurst 的智慧:
> 标题、副标题、块引用、脚注、插图、标题以及其他侵入文本的元素,会在常规行距形成的基础节奏之上产生切分音和变化。这些变化可以并且应该为页面增添活力,但主体文本在每次变化之后也应精准地回到节奏和相位上。——*Robert Bringhurst*,《排版之艺》(https://en.wikipedia.org/wiki/The_Elements_of_Typographic_Style)
## 文本 # (https://vincent.bernat.ch/en/blog/2026-css-vertical-rhythm#text)
三个因素主导着垂直节奏:**字体大小**、**行高**以及**边距或填充**。让我们以 18 像素的字体大小和 1.5 的行高来设定我们的基线:
``
html {
font-size: 112.5%;
line-height: 1.5;
}
h1, h2, h3, h4 {
font-size: 100%;
}
html, body,
h1, h2, h3, h4,
p, blockquote,
dl, dt, dd, ol, ul, li {
margin: 0;
padding: 0;
}
``
CSS 值与单位模块第四级 (https://www.w3.org/TR/css-values-4/) 定义了 `rlh` 单位,它等于根元素的计算行高。自 2023 年以来,所有浏览器都支持它。2 (https://vincent.bernat.ch/en/blog/2026-css-vertical-rhythm#sidenote-postcss) 使用它可以插入垂直空间,或者在更改字体大小时修复行高:3 (https://vincent.bernat.ch/en/blog/2026-css-vertical-rhythm#sidenote-calc)
``
h1, h2, h3, h4 {
margin-top: 2rlh;
margin-bottom: 1rlh;
}
h1 {
font-size: 2.4rem;
line-height: 2rlh;
}
h2 {
font-size: 1.5rem;
line-height: 1rlh;
}
h3 {
font-size: 1.2rem;
line-height: 1rlh;
}
p, blockquote, pre {
margin-top: 1rlh;
}
aside {
font-size: 0.875rem;
line-height: 1rlh;
}
``
我们可以通过在内容上叠加网格来检查结果4 (https://vincent.bernat.ch/en/blog/2026-css-vertical-rhythm#sidenote-grid):
我网站的截图,带有网格叠加层,每行文本都契合网格
使用 CSS `rlh` 单位设置垂直空间对于文本效果很好。你可以使用 Ctrl+Shift+G 显示网格。如果子元素使用的字体具有更高的固有指标,它可能会将行的框拉伸超过配置的行高。5 (https://vincent.bernat.ch/en/blog/2026-css-vertical-rhythm#sidenote-line-height) 一个解决方案是将行高减少到 1。字形会溢出,但不会将行推得更高。
``
code, kbd {
line-height: 1;
}
``
## 响应式图片 # (https://vincent.bernat.ch/en/blog/2026-css-vertical-rhythm#responsive-images)
响应式图片很难在网格上对齐,因为我们不知道它们的高度。CSS 节奏尺寸模块第一级 (https://www.w3.org/TR/css-rhythm-1/) 引入了 `block-step` 属性,用于将元素的高度调整为步长单位的倍数。但大多数浏览器尚未支持它。
使用 JavaScript,我们可以在图片周围添加填充,以便它不打乱垂直节奏:
``
const targets = document.querySelectorAll(".lf-media-outer");
const adjust = (el, height) => {
const rlh = parseFloat(getComputedStyle(document.documentElement).lineHeight);
const padding = Math.ceil(height / rlh) * rlh - height;
el.style.padding = `${padding / 2}px 0`;
};
targets.forEach((el) => adjust(el, el.clientHeight));
``
我网站的截图,带有网格叠加层,图片没有破坏垂直节奏。图片前后可见额外的填充。带填充的图片高度为 216。
得益于使用 JavaScript 计算的额外填充,图片已吸附到网格上。216 可以被 27 整除,这是本例中的行高。由于图片是响应式的,其高度可能会发生变化。我们需要在 `adjust()` 函数周围包装一个 resize observer:
``
const ro = new ResizeObserver((entries) => {
for (const entry of entries) {
const height = entry.contentBoxSize[0].blockSize;
adjust(entry.target, height);
}
});
for (const target of targets) {
ro.observe(target);
}
``
## 表格 # (https://vincent.bernat.ch/en/blog/2026-css-vertical-rhythm#tables)
表格单元格可以将 `1rlh` 设置为其高度,但这会显得局促。使用 `2rlh` 又会浪费太多空间。相反,我们使用增量行距 (https://markboulton.co.uk/journal/incremental-leading/):我们对齐每五行中的一行。
``
table {
border-spacing: 2px 0;
border-collapse: separate;
th {
padding: 0.4rlh 1em;
}
td {
padding: 0.2rlh 0.5em;
}
}
``
为了对齐表格后的元素,我们需要添加一些填充。我们可以重用来自图片的 JavaScript 代码,也可以使用几行 CSS 来计数常规行并计算缺失的垂直填充:
``
table:has(tbody tr:nth-child(5n):last-child) { padding-bottom: 0.2rlh; }
table:has(tbody tr:nth-child(5n+1):last-child) { padding-bottom: 0.8rlh; }
table:has(tbody tr:nth-child(5n+2):last-child) { padding-bottom: 0.4rlh; }
table:has(tbody tr:nth-child(5n+3):last-child) { padding-bottom: 0 }
table:has(tbody tr:nth-child(5n+4):last-child) { padding-bottom: 0.6rlh; }
``
表头单元格的填充是常规单元格的两倍。对于两个常规行,总填充为 2×2×0.2+2×0.4=1.6。我们需要添加 `0.4rlh` 以达到整个表格 `2rlh` 的额外垂直填充。
我网站的截图,带有网格叠加层,表格遵循垂直节奏。表格后可见额外的填充。带填充的表格高度为 405。
每五行中有一行与网格对齐。表格后添加了额外填充以不破坏垂直节奏。405 可以被 27 整除,这是本例中的行高。
---
这一切都不是必要的。但一旦你开始留意,就无法忽视它。在浏览器实现 CSS 节奏尺寸 (https://www.w3.org/TR/css-rhythm-1/) 之前,一点 CSS 技巧和少许 JavaScript 就足以搞定。主体文本现在在每次侵入之后“精准地回到节奏和相位上。” 🎼
相似文章
使用CSS进行抖动处理
本文演示如何使用CSS滤镜和SVG feTurbulence对图像应用抖动效果,以保持一致的视觉风格。
响应式图片的终结
作者作为 RICG 前主席,庆祝一项新的原生 Web 平台特性终于取代了他 14 年前参与标准化的复杂响应式图片标记,带来更简洁的用法和更佳的性能。
告别Tailwind,学习组织CSS
作者反思了从Tailwind CSS迁移到带语义HTML的原生CSS的过程,分享了利用从Tailwind学到的重置、组件和工具类等系统来组织CSS的心得。
深色模式的六个层次(2024)
一篇探讨网页设计中深色模式实现的六个层次的文章,范围从基础的meta标签方法到使用CSS的高级配色方案切换技术。
Olive CSS:Lisp 驱动的类 Tailwind 纯 CSS 工具类框架
Olive CSS 是一个用 Guile Scheme 编写的全新工具类 CSS 框架,语法与 Tailwind 相似,可在任何 Web 项目中直接替代使用。