Skip to content
This page has been auto-translated and may contain errors.View in English

排版

docs.scrimba.com

人们在网上阅读的大部分内容都是文本,而页面给人的感觉很大程度上来自于文本的设置方式。改变字体、调整行距、限制行长,同一段落就会从拥挤令人厌烦变成清爽易读。这不是装饰。这就是排版,是决定你的文字阅读舒适度的一些CSS属性,本章介绍你日常使用的那些。

选择字体

选择字体的属性是font-family,它不是一个字体,而是一个列表。这个列表称为**字体堆栈**:浏览器先尝试第一个字体,如果不可用就回退到下一个,依此类推。

css
body {
  font-family: "Helvetica Neue", Arial, sans-serif;  /* 尝试Helvetica,然后Arial,然后任意无衬线字体 */
}

列表中的最后一个名称应该总是一个通用字体族,如sans-serifserif。这是你的安全网:如果读者设备上没有任何指定的字体,浏览器仍然会显示合理的内容,而不是你没有选择的默认字体。包含空格的字体名称放在引号中;单字词名称不需要引号。

font-family接受逗号分隔的**字体堆栈**,浏览器使用列表中第一个它可以实际渲染的字体。每个名称是前一个的后备,列表应该以通用字体族(sans-serifserifmonospace)结尾,这样总是有最终答案。

css
body {
  font-family: "Inter", "Helvetica Neue", Arial, sans-serif;
}

你有两个广泛的选项来命名字体。系统字体堆栈列出每个操作系统的默认界面字体,所以页面借用读者设备已有的任何字体。下载成本为零,感觉很原生,这就是为什么很多应用都使用它:

css
body {
  font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

另一个选项是网络字体:你加载一个字体文件,这样每个读者都看到相同的字体。你可以从Google Fonts等主机链接一个,或者用@font-face自托管。这使你可以控制外观,但代价是读者要等待下载。

font-family从左到右解析**字体堆栈**,选择浏览器可以渲染的第一个字体族,这就是为什么列表以通用字体族(sans-serifserifmonospace)结尾作为保证的最后手段。两个策略位于你选择的名称后面,它们权衡不同。

系统字体堆栈命名每个平台的原生UI字体,所以页面继承操作系统已经附带的字体。没有下载,所以没有加载延迟和布局移位,文本在每个设备上看起来都很原生。代价是你的页面在平台间看起来略有不同,这对于类似应用的界面来说很好,但对于需要一个一致面孔的品牌来说是错的。

css
body {
  /* 现代系统堆栈:San Francisco、Segoe UI、Roboto,然后是后备 */
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

网络字体是浏览器下载的字体文件,所以每个读者都看到相同的字体。你可以从主机链接一个,或者用@font-face规则自托管,该规则将字体族名称映射到文件。自托管保持字体在你自己的源上,避免第三方请求,并让你控制缓存和font-display行为,该行为控制字体加载时是否在后备中显示文本。

css
@font-face {
  font-family: "Satoshi";
  src: url("/fonts/satoshi.woff2") format("woff2");
  font-weight: 400 700;         /* 一个可变文件覆盖粗细范围 */
  font-display: swap;           /* 立即显示后备文本,加载后交换 */
}

body {
  font-family: "Satoshi", system-ui, sans-serif;  /* 指定网络字体,然后是原生后备 */
}

后备在网络字体中仍然重要的原因是下载可能很慢或失败,而font-display: swap同时渲染你的后备字体族。选择一个与网络字体有相似指标的后备可以防止交换时的布局抖动。

Juno选择字体font-family接受一个列表,不是一个字体,浏览器使用它能找到的第一个。总是以通用字体族(如sans-serif)结尾列表,这样就有安全后备。用引号包装任何包含空格的字体名称。
Juno选择字体 字体堆栈是以通用字体族结尾的后备列表,浏览器采用它可以渲染的第一个字体。系统字体堆栈免费借用设备的原生字体,没有下载,而网络字体加载一个文件,所以每个人都看到相同的面孔。为类似应用的工作选择系统堆栈,当外观必须一致时选择网络字体。
Juno选择字体 堆栈从左到右解析并必须以通用字体族结尾,所以读者总是看到文本。系统堆栈成本为零且从不移位布局但因平台而异;网络字体是一个一致的面孔,代价是下载,你应该用font-display: swap和一个匹配良好的后备来保护它。当你想控制缓存和删除第三方请求时,用@font-face自托管。

文本大小

你用font-size设置文本大小。你可以用像素值,但你应该使用的大小单位是**rem**,一个与页面基础字体大小相关的单位。一个rem等于浏览器的默认文本大小,通常是16px,所以1rem是正常阅读大小,1.25rem稍大一些。

css
body {
  font-size: 1rem;             /* 基础阅读大小,通常16px */
}
h1 {
  font-size: 2rem;             /* 两倍基础大小 */
}

font-size设置文本大小,对于正文你应该用**rem**而不是px来设置大小。一个rem是根元素的字体大小,默认为16px,是读者可以在浏览器设置中改变的值。用rem设置大小意味着你的文本随该偏好缩放;用px设置则锁定它。

css
:root {
  font-size: 100%;             /* 尊重读者的默认值,通常16px */
}
p {
  font-size: 1rem;             /* 如果读者改变他们的默认值则缩放 */
}

rem而不是px设置正文大小,这样尊重读者选择的大小。大小单位章节深入介绍remem、百分比和视口单位如何解析;排版的简短版本是rem给你可缩放、易获取的文本,数学可预测。

font-size接受许多单位,但对于正文,选择涉及可获取性。一个**rem**(root em)相对于根元素(<html>)的font-size,其默认值是读者在浏览器中设置的任何值,通常16px但可自由改变。像素值忽略该偏好。提高默认文本大小以适应舒适度或视觉障碍的读者看到rem大小的文本增长,px大小的文本保持不变,所以px正文副本静悄悄地覆盖读者故意选择的可获取性设置。

css
:root {
  /* 将根保持在读者的默认值;不要用px硬设置为16px */
  font-size: 100%;
}

p {
  font-size: 1rem;             /* 1rem = 读者的根大小,随之缩放 */
}

.lead {
  font-size: 1.125rem;         /* 在16px根处为18px,仍然缩放 */
}

font-size更倾向于rem而不是em,因为em相对于父元素的字体大小,所以em在嵌套时复合:一个em大小的元素在另一个em大小的元素内乘以它,一个嵌套三层深的列表可能会意外缩小或增长。rem总是指单一的根值,所以无论元素坐在多深都保持可预测。注意这与页面缩放不同,页面缩放按比例扩放包括px的所有内容;rem保护的情况是读者特别提高默认字体大小,很多人这样做,而px文本忽略。

Juno文本大小font-size设置文本有多大,rem是你应该选择的单位。一个rem是浏览器的正常文本大小,所以1rem是常规的,2rem是两倍大。避免用px设置正文大小,这是下一个级别深入的内容。
Juno文本大小rem而不是px设置正文大小。一个rem是读者的根字体大小,所以rem中的文本随着他们改变默认值而缩放,px中的文本保持固定。大小单位章节涵盖数学,但对于类型,规则很简短:rem用于任何人阅读的内容。
Juno文本大小rem跟踪读者控制的根字体大小,所以px正文文本无声地覆盖他们故意做出的可获取性选择。也倾向于rem而不是em,因为em相对于父元素,在元素嵌套时复合。这是关于读者的默认文本大小,它与页面缩放是分开的。

粗细和样式

两个属性改变你字母的形状。font-weight控制文本有多粗,font-style打开**斜体**。

css
strong {
  font-weight: bold;           /* 更重、更粗的笔画 */
}
em {
  font-style: italic;          /* 倾斜 */
}

boldnormal是日常粗细关键字。对于斜体,italic倾斜文本,normal保持其直立。

font-weight设置文本的粗细程度,虽然normalbold是熟悉的关键字,但该属性真正接受**数值粗细**,从100900,步长为100400normal映射到的,700bold映射到的。数字很重要,因为许多字体提供关键字无法达到的额外粗细。

css
h1 {
  font-weight: 700;            /* 与bold相同 */
}
.caption {
  font-weight: 300;            /* 轻粗细,没有对应关键字 */
}

font-style: italic在存在真实斜体设计的地方给你字体的真实意大利体设计,是一个单独绘制的倾斜面孔而不是机械倾斜。保留它用于真正的强调或如书名的约定,而不是样式化大块文本,斜体会降低可读性。

font-weight接受从100900的**数值粗细**;normal400的别名,bold700的别名。数字只有在字体实际包含该粗细时才解析为不同的厚度。从只提供400700的字体请求600,浏览器要么舍入到真实粗细,要么通过加粗笔画合成假粗体,看起来比设计的粗细更差。所以可用的粗细取决于你加载的内容:只在两个粗细处链接的网络字体给你两个,无论你写什么数字。

css
h1 {
  font-weight: 800;            /* 仅当字体提供800面孔时才不同 */
}
p {
  font-weight: 400;
}

font-style: italic选择字体的绘制斜体面孔,这是一个具有不同字母形式的单独设计,而不是直立设计的机械倾斜。当不存在斜体面孔时,浏览器通过剪切直立来伪造一个,称为合成斜体,它读起来更便宜。还有oblique,直立设计的真正倾斜,但italic是散文你想要的,因为当字体有一个时,它选择适当绘制的面孔。

Juno粗细和样式font-weight使文本更粗或更轻,font-style: italic倾斜它。关键字boldnormal涵盖你日常所需的大部分。使用斜体用于强调,而不是整个段落,会变得难以阅读。
Juno粗细和样式font-weight真正运行100900,以400为正常,700为粗体,数字释放关键字无法命名的粗细。只有你的字体实际提供的粗细会显示;其余的被伪造或舍入。保留italic用于强调和标题而不是长文本。
Juno粗细和样式 数值粗细从100900运行,但一个数字只有在字体包含该面孔时才成立;否则浏览器舍入或合成看起来更差的假粗体。所以在两个粗细处加载的网络字体给你两个,无论你输入什么。当它存在时,italic选择绘制的意大利体面孔,当它不存在时回退到合成倾斜。

使文本可读的间距

舒适的文本主要是关于空间。line-height控制行之间的间隙,给它一些空间会使段落更容易阅读。

css
p {
  line-height: 1.5;            /* 字体大小的一倍半 */
}

使用像1.5这样的纯数字,没有单位。这意味着"字体大小的一倍半",所以间距随文本增长。拥挤的行是页面感觉难以阅读的最常见原因之一,这个值修复了大部分。

三个属性做了大部分可读文本的工作。line-height设置行之间的垂直空间,你应该给它一个**无单位的值**,如1.5,这意味着元素字体大小的1.5倍。letter-spacing调整字符之间的间隙,对小写大写标题很有用。行的长度与任何一个都一样重要:很长的行读起来很累,所以你用max-width限制行。

css
p {
  line-height: 1.5;            /* 无单位:随字体大小缩放 */
  max-width: 65ch;             /* 将度量上限设置为约65个字符 */
}
.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.05em;      /* 小跟踪,这样大写不会拥挤 */
}

那个ch单位是"0"字符的宽度,所以65ch大约65个字符宽。舒适的度量,每行的字符数,大约在45到75之间,限制它是你可以做的最高影响排版动作之一。

可读性归结为三个控件:行高、字母间距和行长。line-height应该是**无单位的**(1.5,不是24px),原因是继承。无单位的行高作为因子继承,所以每个后代用它自己的字体大小乘以它,每个元素得到按比例的间距。带单位的行高作为计算的长度继承,所以一个字体较大的子元素继承父元素的固定行框,其行重叠。

css
body {
  line-height: 1.5;            /* 作为因子继承:每个元素缩放它 */
}

h1 {
  font-size: 2.5rem;
  /* 继承1.5,计算为1.5 x 2.5rem;固定24px行高会在这里剪裁 */
}

.article {
  max-width: 65ch;             /* ~65个字符的度量 */
  text-wrap: balance;          /* 可选:在标题上均衡参差行 */
}

letter-spacing(跟踪)对于正文最好保持字体的默认值,设计师已经调整过了;小的正值帮助会否则拥挤的全大写和小大写运行,细微的负值可以紧化大显示标题。行长是度量,每行的字符数,舒适的波段大约45到75个字符。用max-widthch("0"字形的前进宽度)中设置它,这样上限跟踪字体,对阅读舒适度的影响超过几乎任何字体选择。

Juno使文本可读的间距line-height设置行之间的空间,约1.5的值使文本更容易阅读得多。将其写成纯数字,没有单位,这样间距随文本增长。拥挤的行是页面感觉难以阅读的主要原因,这修复了大部分。
Juno使文本可读的间距line-height一个无单位的值,如1.5,这样它随每个元素的字体大小缩放。用ch中的max-width限制行长,以保持度量在约45到75个字符,这是最大的可读性优势之一。谨慎使用letter-spacing,主要用于打开大写标题。
Juno使文本可读的间距 保持line-height无单位,这样它作为因子继承并按元素缩放;一个单位继承计算的长度,使大标题重叠。对于正文文本,独立保留letter-spacing,仅为大写或大显示类型轻推。用max-widthch中限制度量接近45到75个字符,它在可读性中击败大部分字体决定。

对齐和装饰

三个属性处理对齐和完成接触。text-align将文本向左、向右或居中移动。text-transform改变大小写,如使文本全部大写。text-decoration添加或移除线条,如下划线。

css
h1 {
  text-align: center;          /* 居中标题 */
}
.button {
  text-transform: uppercase;   /* 显示为全大写 */
  text-decoration: none;       /* 删除链接下划线 */
}

text-transform: uppercase显示大写文本,不需要你重新输入,所以原始内容保持为普通单词。下划线用text-decoration添加或移除。

text-align在其框内定位内联文本(leftrightcenterjustify)。text-transform更改显示案例(uppercaselowercasecapitalize),不改变基础文本,所以屏幕阅读器仍然读真实单词,你的HTML保持干净。text-decoration控制下划线、上划线和删除线。

css
.card-title {
  text-align: center;
}
.nav-link {
  text-decoration: none;              /* 删除默认下划线 */
}
.price--old {
  text-decoration: line-through;      /* 删除线旧价格 */
}

两个值得保留的习惯。避免对网络正文使用text-align: justify,因为没有细粒度的断字控制,它在单词之间打开丑陋的白色空间河。当你删除链接的下划线时,确保另一个提示如颜色仍然将其标记为链接,否则你隐藏了它是可点击的。颜色和背景章节涵盖给链接一个不同的、易获取的颜色。

text-align设置内容在其包含框内的内联对齐。跳过网络正文的justify:浏览器通过拉伸字间来对齐,且没有印刷排版师有的断字和换行控制,它打开白色空间河并伤害可读性超过整洁边缘帮助。

text-transformuppercaselowercasecapitalize)仅改变渲染大小写,不改变源文本,所以可获取性树和你的标记保持真实大小写。那就是做全大写的正确方式:在CSS中转换而不是在HTML中输入大写字母,这样辅助技术不会逐字母读单词,内容保持作为普通散文可编辑。配对大写与一点正letter-spacing,因为以身体的默认跟踪设置的大写读很紧。

text-decoration是线条、样式、颜色和厚度的简写(text-decoration: underline wavy crimson 2px),使用text-decoration-colortext-underline-offset等长手用于更细的控制。常见情况是链接上的text-decoration: none,它伴随的规则是保留另一个可见的视觉提示,因为删除下划线会剥离文本是链接的主要信号。

css
.headline {
  text-transform: uppercase;
  letter-spacing: 0.04em;             /* 大写需要呼吸空间 */
}

a {
  text-decoration-color: currentColor;
  text-underline-offset: 0.15em;      /* 将下划线从基线推开 */
}

text-aligntext-transformline-height继承,所以在容器上设置它们流向内部的文本;选择器章节涵盖定位正确的容器以在其上设置它们。

Juno对齐和装饰text-align将文本向左、向右或中心移动,text-transform: uppercase以大写显示,text-decoration添加或移除下划线等线条。CSS中的大写保持你的实际文本为普通单词,所以你从不重新输入它为大写。当你想删除链接的下划线时,伸出text-decoration: none
Juno对齐和装饰text-align放置内联文本,text-transform仅用于显示改变大小写,text-decoration处理下划线和删除线。在网络上跳过justify,它在单词之间打开丑陋的间隙。如果你删除链接的下划线,保留另一个提示如颜色,这样人们仍然看到它是可点击的。
Juno对齐和装饰 避免对网络正文使用justify;浏览器拉伸字间距并打开白色空间河。用text-transform做全大写,而不是输入大写字母,所以辅助技术读真实单词,源保持干净,添加一点letter-spacing到大写。当你在链接上设置text-decoration: none时,保留另一个可见提示,这样它仍然读作链接。

字体简写和继承

字体属性有一个方便的特性:它们向下传递。在<body>上设置font-family,里面的每个段落、标题和链接都继承它,所以你很少重复自己。

css
body {
  font-family: system-ui, sans-serif;  /* 里面的所有内容都继承这个 */
  line-height: 1.5;
}

因为这个,你的大部分排版都在样式表顶部靠近一个地方,单个元素仅覆盖他们需要不同的东西。

字体属性**继承**:font-familyfont-sizefont-weightfont-styleline-height和颜色都从一个元素传递到其后代,除非被覆盖。这就是为什么你一次在body上设置基础类型并让它流下,CSS如何工作章节深入涵盖。

还有一个font简写,它将几个属性打包到一个声明中,但在你使用它之前有一个值得知道的陷阱。

css
body {
  font: 1rem/1.5 system-ui, sans-serif;   /* 大小/行高 字体族 */
}

顺序是固定的,font-sizefont-family都是必需的。line-height在大小后跟斜杠。因为它是简写,你忽略的任何字体属性都重置为其初始值,这可能会擦除你在别处设置的font-weight

字体属性**继承**沿树向下,所以在容器上设置的font-familyfont-sizefont-weightfont-styleline-height应用于内部的所有内容,直到一个元素覆盖它们。一次在body上设置基础类型并选择性地覆盖是惯用模式;CSS如何工作章节详细说明继承和级联如何决定最终值。

font简写一次设置其中几个,其陷阱是真实的:它是一个简写,所以每个长手它可以设置但你忽略的都重置为其初始值。写font: 1rem/1.5 system-ui,任何早期设置的font-weightfont-stylefont-variant都被无声地擦除回正常。语法也有固定顺序和两个必需部分,font-sizefont-family,带一个可选的line-height用斜杠附加到大小。

css
.callout {
  font: italic 700 1rem/1.5 system-ui, sans-serif;  /* 样式 粗细 大小/行高 字体族 */
}

另外两个高级注释。现代可变字体在一个文件中包装粗细的连续范围(有时宽度和倾斜),所以font-weight: 550可以是一个真实、绘制的值而不是一个舍入的值,当字体暴露该轴线时。整个大小部分的可获取性规则适用于所有这个:用rem保持大小,行高无单位,这样当读者调整他们的默认字体大小或缩放页面时整个类型系统缩放,而不是将文本钉在固定像素网格。

Juno字体简写和继承 字体设置向下传递到元素内部,所以在body上一次设置font-family,所有内容都继承它。这保持你的排版在样式表顶部靠近一个地方。单个元素仅覆盖他们需要改变的位。
Juno字体简写和继承 字体属性继承,所以在body上设置的基础类型流向下,你仅覆盖不同的。font简写将大小、行高和字体族打包在一起,但注意陷阱:你忽略的任何东西都重置为其初始值,这可能会擦除你在别处设置的粗细。其顺序是固定的,大小和字体族是必需的。
Juno字体简写和继承 字体属性继承,所以在body上设置基础类型并选择性地覆盖。font简写重置它忽略的每个长手到其初始值,所以它可以无声地抹去早期设置的粗细或样式;知道那个就触及它。用rem保持大小,行高无单位,这样类型随读者的默认大小和缩放缩放,当你需要来自一个文件的连续粗细范围时依靠可变字体。