当前内容所在位置(可进入专栏查看其他译好的章节内容)
- 第四部分 视觉增强技术 ✔️
- 【第 12 章 CSS 排版与间距】 ✔️
- 12.1 间距设置
- 12.1.1 使用 em 还是 px
- 12.1.2 对行高的深入思考 ✔️
- 12.1.3 行内元素的间距设置
文章目录
- [12.1.2 对行高的深入思考 Factoring in line height](#12.1.2 对行高的深入思考 Factoring in line height)
《CSS in Depth》新版封面
译者按
前面章节在提到行高的设置时,作者往往会说"详见第 12 章";本篇就是对 CSS 行高的一次深入探讨。说是深入,其实也仅仅介绍了文字排版中的冰山一角,但对于还原设计稿中的精确尺寸已经足够了。CSS 很多规则看似简单,但认真深究的话很可能惊掉在座各位的下巴,比如文中提到的那个全新的
leading-trim
属性,看看那篇参考文章就知道了。
12.1.2 对行高的深入思考 Factoring in line height
设计稿中的文字周围还设置了一些间距,具体大小如图 12.3 所示(这里可能有点看不清楚,图中的内容栏是一块白色区域,其所在容器的背景则是很浅的浅灰色。文字区域的顶部和左侧到分栏边缘的距离均为 25px
)。
【图 12.3 正文板块内部和文字周围需要设置的间距】
文字周围环绕的 25px
间隔,可以考虑为板块添加内边距来实现。为了让该间隔对更大的字体作出响应,以实现同步呼吸的效果来确保良好的可读性,这里的间距选择使用相对单位 em
。经计算,25px / 16px = 1.5625em
。
而标题与正文段落间的 30px
就没那么简单了。如果在二者之间指定 30px
的外边距,那么它们的实际间距会接近 36px
。要理解为什么会这样,需要先来看看元素的高度究竟是如何定义的。
在盒模型中,元素的内容盒(content box)被该元素的内边距环绕,再往外则是元素边框,最后是其外边距。但对于这些元素而言,内容盒可不仅仅只有渲染出的文字部分;真正决定内容盒最终高度的,是元素的行高。这个高度覆盖了文字的顶部与底边,如图 12.4 所示。可以看到,当前文字的高度为 1em
,而行高略微超出了文字的上下边缘。
【图 12.4 行高定义了内容盒的高度】
示例页上的行高为 1.4
,这是从 <body>
元素指定并继承过来的。这样一来,对于只有一行的文本元素,其内容盒的行高就是 1.4em
,而文字则基于该行高垂直居中对齐;又因为当前字号为 16px
,因此内容盒的最终高度即为 22.4px
,多出的 6.4px
则平均分配到文字的上方和下方。
因此,如果为标题设置 30px
的底部外边距,则外边距的顶部与标题文字间实际将多出 3.2px
的间距,并且下方段落的内容盒也会多出来 3.2px
(超出的间距是相等的,因为标题和段落具有相同的行高和字号)。这就导致了标题文本和正文段落间的实际间隔为 36.4px
。
注意
印刷领域的设计师习惯使用 行距(leading) 来表示每行文字之间的间距。而在 CSS 中,文字间距是由行高(line height)控制的,不能直接等同为行距。
设计师通常不会在意一两个像素的差异,但多出 6½ 个像素就有点过分了。如果行高比现在还要高,或者元素设置了更大的字号,这样的尺寸偏差还会更加显著。
想要从根本上消除这样的差异,就需要算出多出的检举并在外边距中予以扣除。外边距不能指定为 30px
了,需要扣除 6px
,变为 24px
;再除以 16px
,从而得到相对单位下的 1.5em
。根据下列代码清单 12.3 所示内容同步更新本地样式表:
代码清单 12.3 设置内容板块和段落之间的间距
css
@layer global {
p {
margin-block: 1.5em; /* 为段落添加外边距 */
}
}
/* ... */
@layer modules {
.tile {
background-color: var(--white);
border-radius: 0.3em;
padding: 1.5625em; /* 在内容板块的内部指定内边距 */
}
.tile > h4 { /* 在内容板块的标题下方设置外边距 */
margin-block: 0 1.5em;
}
上述代码中,外边距 1.5em
已在全局生效,因此页面中的所有段落都将具有相同的间距。然后在内容板块的标题下方(即 .tile > h4
元素下方)重复该操作,这样即便后面没有段落内容,标题下方的间距都将保持不变。由于存在外边距折叠效应,这两个外边距会相互重叠,从而在标题和段落间产生一个标准的 30px
间距。
说明
CSS 即将推出一个全新的属性
leading-trim
,用于消除内容盒上下边缘的多余间距,不过该属性目前尚未获得任何浏览器的官方支持。想了解更多leading-trim
的相关介绍,可以参考 Ethan Wang 刊登在 Medium 网站的这篇文章《Leading-Trim: The Future of Digital Typesetting 》(https://mng.bz/67PR)。译注:
截至 2024 年 12 月 10 日 Can I Use 网站最新的统计资料,各浏览器对
leading-trim
属性的支持率仅为 0.09%,目前仅 Safari 浏览器提供了相关支持;不过后续进展非常值得关注。【补图1:Can I Use 网站公布的各大浏览器对 leading-trim 属性的支持情况(截至 2024 年 12 月 10 日)】
视觉稿还需转换的最后一处间距,位于巨幅主图中的标语附近,如图 12.5 所示:
【图 12.5 设计稿要求在标语上方预留 95px 的间距,而在其下方预留 16px 的间距(即标语和按钮之间)】
标语处的行高同样会影响到这些间距的设置,因为它的字号更大。标语处的字号为 1.95rem
,乘以基准字号 16px
,即 31.2px
;再乘以 1.4 倍的行高,算得的最终行高大小为 43.68px
,因此会在文字上下分别多出约 6px
的间距。
既然行高已经在文字上方占据了 6px
,因此只需再增加 89px
的间隔就能满足上方间距的要求;同理,标语下方也只需再增加 10px
的间距,就能满足视觉稿中标语下方的间距要求。由于其间涉及大量的算术运算,最简单的解决办法通常是和设计师一起坐下来,在浏览器中实时修改这些间距值,直到获得设计师的首肯。
译注
为方便对照,这里直接给出示例页主图部分的 HTML 片段:
html<div class="hero"> <div class="hero__inner"> <h2>Team collaboration done right</h2> <a href="/sign-up" class="button button--cta">Get started</a> </div> </div>
明确要在标语上下位置添加的具体间距尺寸后,就可以将其更新到样式表中了。具体样式详见代码清单 12.4。根据给出的内容同步更新本地样式表,变更位置已添加注释说明。此外还在 hero__inner
容器上设置了最小高度(译注:即 min-block-size
),以确保能像设计稿那样撑开一大块屏幕空间。
代码清单 12.4 在主图中设置标语和按钮的位置
css
.hero {
background: url(collaboration.jpg) no-repeat;
background-size: cover;
margin-bottom: 40px;
}
.hero__inner {
max-inline-size: 1080px;
margin-inline: auto;
min-block-size: 40svh;
padding-block: 89px; /* 用新计算的间距值替换此前的估值 */
padding-inline-end: 12.5em;
text-align: right;
}
.hero h2 {
margin-block: 0 10px; /* 定义标语和按钮间的间距大小 */
font-size: 1.95rem;
}
hero__inner
的顶部内边距定义了标语上方所需的间距。尽管设计稿中并没有标注其右侧的内边距尺寸,但上述代码中也进行了相应设置(译注:即 12.5em
)。最后将标语元素的顶部外边距设为 0
,这样就不用担心在 hero__inner
的内边距上再多出额外的间距了。
译注
在复盘本篇要点时,偶然发现作者提到的那篇介绍
leading-trim
属性的文章没有完整的翻译版,要么是节选的,要么是收费的(有点过分了)。拟计划完成本章所有内容后,再来翻译这篇文章并放到本专栏。敬请关注!
关于《CSS in Depth》(中译本书名《深入解析 CSS》)
第 1 版 | 第 2 版 | |
---|---|---|
读者评分 | 原版:4.7 (亚马逊);中文版:9.3(豆瓣) | 原版:5.0(亚马逊);中文版:暂无,待出版 |
出版时间 | 原版:2018 年 3 月 ;中文版:2020 年 4 月 | 原版:2024 年 7 月;中文版:暂无,待出版 |
原价 | 原版:$44.99 ;中文版:¥139.00 | 原版:$59.99;中文版:暂无,待出版 |
现价 | 原版:$36.49 ;中文版:¥52.54 起步 | 原版:$52.09;中文版:暂无,待出版 |
原版国内预订 | 起步价 ¥461.00 | 起步价 ¥750.00 |
本专栏为该书第 2 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!
目前已完结的章节(可进入本专栏查看详情,连载期间完全免费):
- 第一章 层叠、优先级与继承(已完结)
- 1.1 层叠
- 1.2 继承
- 1.3 特殊值
- 1.4 简写属性
- 1.5 CSS 渐进式增强技术
- 1.6 本章小结
- 第二章 相对单位(已完结)
- 2.1 相对单位的威力
- 2.2 em 与 rem
- 2.3 告别像素思维
- 2.4 视口的相对单位
- 2.5 无单位的数值与行高
- 2.6 自定义属性
- 2.7 本章小结
- 第三章 文档流与盒模型(已完结)
- 3.1 常规文档流
- 3.2 盒模型
- 3.3 元素的高度
- 3.4 负的外边距
- 3.5 外边距折叠
- 3.6 容器内的元素间距问题
- 3.7 本章小结
- 第四章 Flexbox 布局(已完结)
- 4.1 Flexbox 布局原理
- 4.2 弹性子元素的大小
- 4.3 弹性布局的方向
- 4.4 对齐、间距等细节处
- 4.5 本章小结
- 第五章 网格布局(已完结)
- 5.1 构建基础网格
- 5.2 网格结构剖析 (上)
- 5.2.1 网格线的编号(下)
- 5.2.2 网格与 Flexbox 配合(下)
- 5.3 两种替代语法
- 5.3.1 命名网格线
- 5.3.2 命名网格区域
- 5.4 显式网格与隐式网格(上)
- 5.4.1 添加变化 (中)
- 5.4.2 让网格元素填满网格轨道(下)
- 5.5 子网格(全新增补内容)
- 5.6 对齐相关的属性
- 5.7 本章小结
- 第六章 定位与堆叠上下文(已完结)
- 6.1 固定定位
- 6.1.1 创建一个固定定位的模态对话框
- 6.1.2 在模态对话框打开时防止屏幕滚动
- 6.1.3 控制定位元素的大小
- 6.2 绝对定位
- 6.2.1 关闭按钮的绝对定位
- 6.2.2 伪元素的定位问题
- 6.3 相对定位
- 6.3.1 创建下拉菜单(上)
- 6.3.2 创建 CSS 三角形(下)
- 6.4 堆叠上下文与 z-index
- 6.4.1 理解渲染过程与堆叠顺序(上)
- 6.4.2 用 z-index 控制堆叠顺序(上)
- 6.4.3 深入理解堆叠上下文(下)
- 6.5 粘性定位
- 6.6 本章小结
- 第七章 响应式设计(已完结)
- 7.1 移动端优先设计原则(上篇)
- 7.1.1 创建移动端菜单(下篇)
- 7.1.2 给视口添加 meta 标签(下篇)
- 7.2 媒体查询(上篇)
- 7.2.1 深入理解媒体查询的类型(上篇)
- 7.2.2 页面断点的添加(中篇)
- 7.2.3 响应式列的添加(下篇)
- 7.3 流式布局
- 7.4 响应式图片
- 7.5 本章小结
- 第八章 层叠图层及其嵌套
- 8.1 用 layer 图层来操控层叠规则(上篇)
- 8.1.1 图层的定义(上篇)
- 8.1.2 图层的顺序与优先级(下篇)
- 8.1.3 revert-layer 关键字(下篇)
- 8.2 层叠图层的推荐组织方案
- 8.3 伪类 :is() 和 :where() 的用法
- 8.4 CSS 嵌套的使用
- 8.4.1 嵌套选择器的使用
- 8.4.2 深入理解嵌套选择器
- 8.4.3 媒体查询及其他 @规则 的嵌套
- 8.5 本章小结
- 第九章 CSS 的模块化与作用域
- 9.1 模块的定义
- 9.1.1 模块和全局样式
- 9.1.2 一个简单的 CSS 模块
- 9.1.3 模块的变体
- 9.1.4 多元素模块
- 9.2 将模块组合为更大的结构
- 9.2.1 模块中多个职责的拆分
- 9.2.2 模块的命名
- 9.3 CSS 的作用域
- 9.3.1 CSS 作用域的就近原则
- 9.3.2 划定作用域的边界
- 9.3.3 CSS 中的隐式作用域
- 9.3.4 关于 CSS 作用域与层叠图层
- 9.4 CSS 模式库
- 9.5 本章小结
- 第十章 CSS 容器查询
- 10.1 容器查询的一个简单示例
- 10.1.1 容器尺寸查询的用法
- 10.2 深入理解容器
- 10.2.1 容器的类型
- 10.2.2 容器的名称
- 10.2.3 容器与模块化 CSS
- 10.3 与容器相关的单位
- 10.4 容器样式查询的用法
- 10.4.1 将模块与所在容器解耦
- 10.4.2 减少重复代码
- 10.5 本章小结
- 第 11 章 颜色与对比
- 11.1 通过对比进行交流
- 11.1.1 模式的建立
- 11.1.2 还原设计稿
- 11.2 颜色的定义
- 11.2.1 色域与色彩空间
- 11.2.2 CSS 颜色表示法(RGB、Hex、HSL、HWB、LAB/OKLAB、LCH/OKLCH)
- 11.3 利用 OKLCH 处理颜色(上篇)
- 11.3.4 从页面其他颜色衍生出新颜色(下篇)
- 11.4 思考字体颜色的对比效果
- 11.5 本章小结
- 附录
- 附录A:CSS 选择器参考
- 附录B:CSS 预处理器简介