【CSS in Depth 2 精译_072】第 12 章 CSS 排版与间距概述 + 12.1 间距设置(上):究竟该用 em 还是 px

当前内容所在位置(可进入专栏查看其他译好的章节内容)

  • 第四部分 视觉增强技术 ✔️
  • 【第 12 章 CSS 排版与间距】 ✔️
    • 12.1 间距设置 ✔️
      • 12.1.1 使用 em 还是 px ✔️
      • 12.1.2 对行高的深入思考
      • 12.1.3 行内元素的间距设置

文章目录

  • [第 12 章 排版与间距 Typography and spacing](#第 12 章 排版与间距 Typography and spacing)
    • [12.1 间距 Spacing](#12.1 间距 Spacing)
      • [12.1.1 使用 em 还是 px(Using ems vs. px)](#12.1.1 使用 em 还是 px(Using ems vs. px))

《CSS in Depth》新版封面

译者按

本篇又将开启新一章的学习,全新修订的第 12 章同样将站在设计师的角度,重点关注页面样式的精修与微调。自学第一版时这些章节我都是能跳过便跳过,因为工作上催得太紧了,很多知识点都是边干边查边消化,事后也疏于复盘,结果现在还得老老实实回来补上这一课。很多事情就是这样,省力在前往往意味着吃苦在后。有些人即便撞了南墙还不死心,估计是知道返工的活最磨人吧,于是拖着拖着就放弃挣扎了。相比之下,我还算比较幸运的,没有选择躺平。希望你也是。

第 12 章 排版与间距 Typography and spacing


本章概要

  • 元素间距的微调
  • 用 Web 字体打造页面独特观感
  • 谷歌字体 API 的用法
  • 字体间距的调整(字距、行距与行高)
  • 影响 Web 字体性能的因素及优化策略
  • 可变字体(variable fonts)的用法

本章将继续构建上一章留下的示例页。目前已经定义好了颜色,页面布局也大致准备就绪了。剩下的工作还包括精修页面元素间的间距,以及改用 Web 字体来增强页面的视觉趣味性等。它们看似是两个不相关的主题,但在某些关键问题上是存在相互作用的。CSS 中含有大量控制布局、间距及字号的属性(properties),因此有必要将它们与某些通用的间距调整方案结合起来进行考察。

排版是与印刷设备同样古老的一种艺术形式,也因此成为本书唯一一个有着数百年发展历史的古老话题。本书不会从头至尾介绍排版的方方面面,而是探讨排版的一些核心要素,并教会您怎样在现代 Web 开发中应用这些知识。

12.1 间距 Spacing

如果上一章您一直紧跟我的节奏在本地同步练习的话,此刻应该已经实现了示例页的颜色配置和大致的布局。示例页的 HTML 标记详见 代码清单 11.1 (译注:位于上一章的 11.1.2 小节);而 CSS 代码则是在后续讲解中逐步完善的,此刻也应该与本章中的示例代码保持一致。如若不然,也可以从示例代码仓库中复制文件 listing-11.08.html(详见 https://github.com/CSSInDepth/css-in-depth-2/blob/main/ch11/listing-11.08.html)。

下面重点关注设计稿中标注的那些精确间距。根据设计师选用的不同工具,间距的微调往往是开发过程中一项较为枯燥的工作。虽然现代化的设计工具能有效缓解这个问题,但在后期审查页面时,可能还会与设计师反复沟通调整,明确一些需要修改的地方,或者跟视觉稿不一致的实现。

这部分工作主要涉及元素外边距的正确设置。人们往往是从最容易的地方着手,哪怕后续会面临进一步调整。这里要考虑的问题主要有两个:一是相对单位的引入与否;二是考虑行高对垂直间距的实际影响。

12.1.1 使用 em 还是 px(Using ems vs. px)

考虑使用相对单位还是绝对单位,是非常重要的决定。因为设计师一般使用像素来标注距离,因此使用绝对单位会相对容易。但启用相对单位,无论是选 em 还是 rem,都可以带来很多好处。

我们来看一下导航菜单里标注的距离(如图 12.1 所示)。设计稿要求每个导航菜单项之间必须留有 10px 的间距,同时其底边与导航条的底边之间的间距也为 10px

【图 12.1 每个导航菜单项之间及周围都需要空出 10px】

在第二章中,我们了解了使用相对单位的各种好处,因此有必要想清楚对哪些尺寸适合相对单位,而哪些适合用像素。是考虑快刀斩乱麻,将所有尺寸都转为 em 或者 rem?还是因地制宜,根据页面每个设计元素的具体情况来决定?如果考虑间距会随着用户设置的不同字号做同步缩放,那么就应该选用相对单位 emrem;否则使用像素单位 px 就完全足够了。基于这样的考虑,在实际开发中,我通常更倾向于对一些偏小的尺寸应用相对单位(em),特别是那些环绕在文字或按钮周围的尺寸;而稍大一些的容器间隔或内部间距受响应式设计的影响没那么敏感,因此保留像素单位 px 即可。

在我带您了解示例页中的间距设置时,我会指出选择某种方式的理由;但请注意,这些意见或观点难免会带有主观色彩,给出的解决方案也可能并非唯一正确的答案。

按照设计规范,导航栏中的间距尺寸需要在菜单项四周留出 10px 的距离(如图 12.1 所示)。由于它们算小尺寸元素,且文字周围还得留些内边距,因此考虑使用相对单位 em 来设置它们的间距。

鉴于基准字号为 16px,可以通过目标尺寸除以基准字号来算出 em 的值,即 10 / 16 = 0.625。因此该间距为 0.625em;再将其放入样式表中,相关样式代码如下列代码清单 12.1 所示。需要变更的地方都标有注释。

译注

为方便对照,这里直接给出示例页的相关 HTML 标记:

html 复制代码
<nav class="nav-container">
  <div class="nav-container__inner">
    <a class="home-link" href="/">Ink</a>
    <ul class="top-nav">
      <li><a href="/features">Features</a></li>
      <li><a href="/pricing">Pricing</a></li>
      <li><a href="/support">Support</a></li>
      <li class="top-nav__featured"><a href="/login">Login</a></li>
    </ul>
  </div>
</nav>

代码清单 12.1 使用内边距和外边距来设置导航菜单的间距

css 复制代码
.nav-container {
  background-color: var(--medium-green);
}
.nav-container__inner {
  display: flex;
  justify-content: space-between;
  max-inline-size: 1080px;
  margin-inline: auto;
  padding: 0.625em 0; /* 给整个导航栏设置 10px 的上下内边距 */
}

/* ... */

.top-nav {
  display: flex;
  list-style-type: none;
  margin: unset; /* 移除浏览器默认的列表元素外边距样式 */
  gap: 0.625em; /* 各导航菜单项间添加 10px 的水平外边距*/
}

处理间距时,需要知道什么时候该用内边距,什么时候该用外边距。在本例中,容器 nav-container__inner 应该使用内边距来设置垂直间隔,以便对整个容器生效,让其中靠左显示的页面标题(即 a.home-link 元素)和 top-nav 列表自带上下间距;而导航菜单项之间的水平间距则用到了 Flexbox 布局中的间隙(gap),因为我只希望间距出现在各子项之间。此外,也可以通过设置外边距来达到相同效果 [1](#1)

再来看看巨幅主图的底边和三个内容栏之间的垂直间隔。如图 12.2 所示,设计稿展示了这些间距的测量结果。可以看到,无论对于带背景图片的主图元素还是设置了背景色的三个内容栏元素,标出的间隔都仅对元素外围生效,因此需要使用外边距来处理这两个间隔。

【图 12.2 主图下方(40px)及内容栏(25px)之间的页面外边距效果】

在本例中,我认为这些间隔无需随字号大小而同步缩放,因此就保留了像素单位 px。具体设置详见代码清单 12.2。上一章其实已经设置了主图下方的外边距 40px,这里再写一遍以强调其用意。将下列示例代码中 tile-row 元素的间隙设置(即 gap 声明)也添加到本地样式表:

代码清单 12.2 为主图下方及内容栏之间设置外边距

css 复制代码
.hero {
  background: url(collaboration.jpg) no-repeat;
  background-size: cover;
  margin-block-end: 40px; /* 确保主图下方有 40px 的间距 */
}

/* ... */

.tile-row {
  display: flex;
  gap: 25px; /* 各分栏之间保持 25px 的间距*/
}
.tile-row > * {
  flex: 1;
}

像这种容器(带有背景图片或者背景颜色的),它们之间的间隔设置往往很简单。如果需要调整文本行之间的间距,例如段落或者标题中的文本,可能会略显麻烦(a little more finicky)。




关于《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 预处理器简介

  1. 译注:若采用外边距实现起来会比较繁琐。上一版就是用的左外边距,需要和猫头鹰选择器搭配使用,写作:.top-nav > li + li { margin-left: 0.625em; }↩︎
相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom11 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试