line-height 的作用
line-height 设置每行文字的高度。这个高度与字体本身所需高度之间的差值会被一分为二,分别加在字母的上方和下方,所以它就是控制行间距的方法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Line height</title>
<style>
body { font-family: system-ui, sans-serif; font-size: 16px; color: #111827; }
.row { display: flex; gap: 16px; align-items: flex-start; }
p { margin: 0; width: 200px; padding: 8px; background: #e5e7eb; }
.tight { line-height: 1; }
.comfy { line-height: 1.5; }
.double { line-height: 2; }
</style>
</head>
<body>
<div class="row">
<p class="tight">line-height: 1. Lines touch and long text is hard to follow.</p>
<p class="comfy">line-height: 1.5. Comfortable spacing for a paragraph.</p>
<p class="double">line-height: 2. Double spacing, like a draft.</p>
</div>
</body>
</html>
三个段落都使用 16px 的字体。各行的高度分别是 16px、24px 和 32px。
取值:无单位、长度、百分比、normal
| 值 | 示例 | 16px 文字的行高 | 子元素继承到的是 |
|---|
| 数字 | 1.5 | 24px | 数字本身(1.5),每个元素重新计算 |
| 长度 | 24px、1.5em、1.5rem | 24px | 计算后的长度(24px) |
| 百分比 | 150% | 24px | 计算后的长度(24px) |
normal | normal | 由字体决定,通常约为 1.2 | normal |
前两行在单个元素上看起来一样。只有当子元素的字号不同时才会显出区别,这就是下一节的内容。
为什么无单位是正确的默认选择
1.5em 或 150% 的行高会在父元素上被换算成像素,子元素继承的就是这些像素。字号更大的子元素于是会得到比字母还矮的行。无单位的 1.5 则以数字本身被继承,再乘以每个子元素自己的字号。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Unitless vs em</title>
<style>
body { font-family: system-ui, sans-serif; font-size: 14px; color: #111827; }
.box { width: 220px; padding: 8px; margin-bottom: 12px; background: #e5e7eb; }
.em { line-height: 1.5em; } /* 21px, inherited as 21px */
.unitless { line-height: 1.5; } /* inherited as 1.5 */
h2 { font-size: 32px; margin: 0; }
</style>
</head>
<body>
<div class="box em">
<!-- line-height: 1.5em -->
<h2 id="em-h">A heading that wraps</h2>
</div>
<div class="box unitless">
<h2 id="num-h">A heading that wraps</h2>
</div>
<p id="out"></p>
<script>
const lh = (id) => getComputedStyle(document.getElementById(id)).lineHeight;
document.getElementById('out').textContent =
'em box heading: ' + lh('em-h') + ', unitless box heading: ' + lh('num-h');
</script>
</body>
</html>
两个标题都换成了两行。第一个继承了 21px 的行高,而字母是 32px,所以各行互相重叠。第二个得到 32 × 1.5 = 48px 的行高。在 body 上用数字设置一次 line-height,大多数页面就再也不用管它了。
自己试试不同的值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Line height tester</title>
<style>
body { font-family: system-ui, sans-serif; color: #111827; }
#sample { width: 320px; margin-top: 12px; padding: 8px; background: #e5e7eb; }
</style>
</head>
<body>
<label>line-height: <input id="val" value="1.5" size="12"></label>
<p id="sample">Line height changes the space between the lines of this paragraph. Type a number, a length or a percentage and watch the gaps change.</p>
<p><code id="out"></code></p>
<script>
const sample = document.getElementById('sample');
const input = document.getElementById('val');
const show = () => {
sample.style.lineHeight = input.value;
document.getElementById('out').textContent =
'computed: ' + getComputedStyle(sample).lineHeight;
};
input.addEventListener('input', show);
show();
</script>
</body>
</html>
试试 1、2、30px、200% 和 normal。Chrome 对 normal 报告的是这个词本身而不是像素值,因为它的大小来自字体。
易读文字的合适取值
- 正文: 1.4 到 1.6。行越长,需要的行高越大,眼睛才能找到下一行的开头。
- 标题: 1.1 到 1.3。大字号配 1.5 的行距,看起来就像几行分开的文字,而不是一个标题。
- 按钮和单行标签: 1 到 1.25,高度用内边距来撑。
在无障碍方面,WCAG 成功标准 1.4.12 要求读者把行高设为字号的 1.5 倍时页面仍能正常使用,所以不要给文本框设置会把文字裁掉的固定高度。
让单行文字垂直居中
当一个盒子里恰好只有一行文字时,让 line-height 等于盒子高度,文字就会位于垂直方向的正中,因为多余的空间被平均分到了上下两侧:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Single line centering</title>
<style>
body { font-family: system-ui, sans-serif; }
.badge {
height: 40px;
line-height: 40px;
padding: 0 16px;
width: max-content;
background: #2563eb;
color: white;
border-radius: 20px;
}
</style>
</head>
<body>
<div class="badge" id="badge">One line, centered</div>
</body>
</html>
一旦文字换成两行,这个方法就失效了,因为每行都有 40px 高。对于可能换行的内容,请改用 flexbox 居中,见 让 div 居中 一页。
font 简写属性
font 简写属性用斜杠同时设置字号和行高:
body {
font: 16px/1.5 system-ui, sans-serif; /* size 16px, line-height 1.5 */
}
简写属性会重置所有它没有提到的字体属性(如果省略斜杠部分,line-height 也会被重置为 normal),所以要把它写在任何单独的 font-* 规则之前。
常见错误
- 在容器上使用
em 或 %。 子元素会继承一个固定长度。请使用无单位的数字。
- 给文本框设置固定的
height。 文字换行或读者加大间距时,内容就会溢出。让内容决定高度。
- 正文行距太紧。
line-height: 1 会让段落难以阅读。从 1.5 开始。
- 以为
line-height 能增加段落之间的距离。 那是段落上的 margin 的工作。
- 依赖
normal。 它因字体而异,所以换字体时布局会发生变化。