定义 Web 内容可访问性标准的组织 Web 内容无障碍指南 (WCAG) 没有指定 Web 的最小字体大小。
但我们知道,文本太小会影响可读性,而文本太大则难以阅读。 那么,如何确保字体大小符合可访问性标准呢? 我们应该遵循哪些最佳实践才能实现可访问的阅读体验?
答案是:这取决于。 我们稍后会探讨一些具体的细节,但现在,让我们先了解 WCAG 对字体的要求。
大小、对比度和 300 种字母
首先是 调整文本大小。 我们希望为视力障碍用户提供一种选择文本显示方式的方法。 并非以一种疯狂的方式。 更像是能够将文本大小增加 200%,同时保持可读性,避免内容碰撞和重叠。
其次是 对比度。 这就是我之前说“这取决于”的原因,因为符合可访问性标准的字体大小取决于多种因素。 文本必须遵循至少 4.5:1 的 对比度比率,大型文本的对比度比率至少为 3:1。 您可以使用 WebAIM 的对比度检查器 等工具来确保文本符合指南。 Stacy Arrelano 关于颜色对比度的深入探讨 对对比度比率的计算方式进行了很好的解释。
世界上大约有 300 种字母。 某些字符简单易读,即使在较小的尺寸下也能保持清晰;而另一些字符则非常复杂,如果使用相同的大小,将会丢失重要的细节。 这就是为什么规范无法定义满足对比度比率规范的字体大小的原因。
当我们谈论“文本”和“大型文本”大小的时候,我们指的是 规范 中所说的“用于这些语言的最小大字号,以及下一个更大的标准大字号”。 例如,为了满足使用罗马文本的 AAA 标准,“大型”文本大小为 18 点。 由于我们生活在一个具有不同屏幕密度的世界,规范以点而不是像素来衡量大小,在某些显示器上,18pt 等于 24px。 对于其他字体,例如 CJK(中文、日语、韩语)或阿拉伯语,像素大小会不同。 以下是“Hello”这个词与其他三种语言的对比
Hello สวัสดี مرحبا 你好
简而言之,WCAG 指定的是对比度,而不是大小。

好消息是:浏览器的默认样式是可访问的,我们可以利用它们来构建可访问的字体大小策略。 让我们看看如何实现。
关注比例,而不是大小
浏览器首先加载其默认样式(也称为“用户代理样式表”),然后这些样式会级联到作者的样式(我们定义的样式),最后这两者都会级联并被用户的样式覆盖。
正如 Adrian Sandu 在其关于 rem CSS 单位的 文章 中提到的那样
[...] 互联网档案的开发人员进行了一项 经验研究,结果表明,相当多的用户会更改浏览器设置中的默认字体大小。
我们也无法完全控制 font-family
属性。 内容可能会被翻译,自定义字体系列可能会加载失败,甚至可能会被更改。 例如,OpenDyslexic 是一种专门为有阅读障碍的用户设计的字体。 在某些情况下,我们甚至可能 明确允许在有限的字体集中切换字体。
因此,在定义字体时,我们必须避免阻碍用户或设备更改我们的样式,并放弃一些假设:我们无法确定内容最终会出现在哪里,也无法确定用于显示内容的确切大小、语言或字体。
但是,我们可以控制的一件事是:比例。
通过使用 CSS 相对单位,我们可以将内容设置为与环境告诉它应该是什么样的比例。 WCAG 建议使用 em 单位来定义字体大小。 有很多出版物讨论了使用 ems 和 rems 的好处,这超出了本文的范围。 我想说的是,对所有内容都使用 rems 和 ems,即使是除字体大小之外的其他属性(边框除外,边框我使用像素)。
避免设置基本字体大小
我建议不要在 :root
、<html>
或 <body>
元素上设置 font-size
,而应该让浏览器的默认大小作为基线,从该基线开始级联我们自己的样式。 由于默认大小是可访问的,因此内容也是可访问的。 WACAG 2.2 工作草案 指出
在使用文本时,如果没有指定字体大小,则主要浏览器用于未指定文本的最小字体大小将是一个合理的字体大小假设。
当然,这条规则也有例外。 例如,当使用复杂、细微或 x 高度过短的字体时,您可能需要考虑将基本字体大小增加一些,以获得正确的对比度。 请记住,规范定义的是对比度,而不是大小。
笔画极其细微或具有非寻常特性和特点的字体,会导致其字母形式的熟悉度降低,因此更难阅读,尤其是在对比度较低的情况下。
同样地,用户可能会更改基本字体大小以适应自己的需求。 视力障碍用户可能希望选择更大的尺寸,而视力良好的人可能希望选择更小的尺寸以获得更大的屏幕空间。
关键是比例:我们通过利用默认基线来设置主文本大小,从而定义内容各部分的大小差异。
:root {
/* Do not set a font-size on a :root, body nor html level */
/* Let your main text size be decided by the browser or the user settings */
}
.small {
font-size: .8rem;
}
.large {
font-size: 2rem;
}
标题怎么办?
由于标题会创建文档大纲,帮助屏幕阅读器浏览文档,因此我们不定义标题大小的类型选择器。 标题顺序是 WCAG 标准:标题元素应该按降序排列,不能跳过级别,这意味着 h4
应该紧跟在 h3
之后。
有时,将所有标题的字体大小重置为 1rem
是一个很好的策略,可以强制将视觉效果与含义区分开来。
如何使用像素?
rem
或 em
大小都是相对于其他东西的。 例如,rem
相对于 <html>
元素计算大小,而 em
则根据其自身元素的大小计算。 这可能会让人感到困惑,尤其是对于那些习惯于使用像素的人来说。
那么,我们如何才能在使用相对单位的同时仍然以像素为单位思考呢?
在大多数情况下,排版层次结构都是以像素为单位设计的。 由于我们了解用户代理样式表,并且知道所有主要浏览器的默认字体大小都是 16px
,因此我们可以将主文本的大小设置为该大小,并使用 rem
单位按比例计算其余部分的大小。
浏览器名称 | 基本字体大小 |
---|---|
Chrome v80.0 | 16px |
FireFox v74.0 | 16px |
Safari v13.0.4 | 16px |
Edge v80.0(基于 Chromium) | 16px |
Android(三星、Chrome、Firefox) | 16px |
Safari iOS | 16px |
Kindle Touch | 26px(由于是高密度屏幕,因此渲染为 16px) |
现在,让我们探讨三种在 CSS 中使用相对大小的方法,将这些像素转换为 rem 单位。
方法 1:62.5% 规则
为了无缝地将像素转换为 rem,我们可以将根大小设置为 62.5%
。这意味着 1rem
等于 10px
:root {
font-size: 62.5%; /* (62.5/100) * 16px = 10px */
--font-size--small: 1.4rem; /* 14px */
--font-size--default: 1.6rem; /* 16px */
--font-size--large: 2.4rem; /* 24px */
}
.font-size--small {
font-size: var(--font-size--small);
}
.font-size--default {
font-size: var(--font-size--default);
}
.font-size--large {
font-size: var(--font-size--large);
}
calc()
函数
方法 2:使用 我们还可以使用 CSS calc()
来计算大小,方法是将像素值除以我们假设大多数浏览器具有的字体基线
:root {
--font-size--small: calc((14/16) * 1rem); /* 14px */
--font-size--default: calc((16/16) * 1rem); /* 16px */
--font-size--large: calc((24/16) * 1rem); /* 24px */
}
.font-size--small {
font-size: var(--font-size--small);
}
.font-size--default {
font-size: var(--font-size--default);
}
.font-size--large {
font-size: var(--font-size--large);
}
方法 3:使用“像素到 rem”函数
类似于 calc()
,我们可以利用预处理器来创建一个“像素到 rem”函数。有很多种实现方法,包括 这个 Sass 混合 和 styled-components polish。
:root {
--font-size--small: prem(14); /* 14px */
--font-size--default: prem(16); /* 16px */
--font-size--large: prem(24); /* 24px */
}
.font-size--small {
font-size: var(--font-size--small);
}
.font-size--default {
font-size: var(--font-size--default);
}
.font-size--large {
font-size: var(--font-size--large);
}
甚至可以使用纯 CSS 创建一个“像素到 rem”函数
拥抱多元的网络!
底线是:我们无法控制内容的消费方式。用户拥有个人浏览器设置,可以放大和缩小,以及其他各种自定义阅读体验的方式。但我们确实拥有最佳 CSS 实践,可以用来在这些偏好中维护良好的用户体验
- 使用比例而不是显式大小。
- 依靠默认浏览器字体大小,而不是在
:root
、<html>
或<body>
上设置它。 - 使用
rem
单位来帮助内容随着用户的个人偏好进行缩放。 - 避免做出假设,让环境决定内容的消费方式。
特别感谢 Franco Correa 在撰写这篇文章时提供的帮助。
将 rem 字体样式与基于 px 的布局和媒体查询混合起来很棘手,它们不会一起缩放。在 500px 宽的框内以 1rem 大小看起来很好的文本会显得太大,因为容器根本没有改变。
根据我们的经验,用户更有可能为浏览器设置默认缩放级别(或只在页面上缩放),而不是设置默认的“不缩放”(约占 2% 的用户)。
当浏览器缩放行为不一致时,rem 是一个很好的解决方法。它们现在不再值得使用。
最大的视觉文本可访问性优势可以在 WCAG 的指南中找到。
带 ARIA 标签和状态的有意义文本也不应该在这个讨论中被忽略,除非我们只是在谈论视觉可访问性。
您是否建议使用基于 rem 的布局?
我建议要么全用,要么都不用,不要混合使用绝对值和相对值。
感谢您收集这些信息。我也是从不设置基础字体大小的支持者,而是转而使用用户偏好。
为了对这里的一些建议进行补充,在设置字体大小时
注意任何基于视窗单位(
vw
或vh
)的大小;避免在视窗大小媒体查询中更改字体大小;
行长很重要,所以要注意不要让文本行太长;
在您拥有良好的测试流程之前,避免使用
min()
、max()
和clamp()
;注意,当用户在浏览器设置中更改字体大小时,以
px
设置的类型不会受到影响,所以也许应该完全避免使用px
。我在我的文章 响应式类型和缩放 中提供了这些问题示例。
关于 OpenDyslexic 的一个简短说明来自 2013 年一项有 48 名参与者参与的研究(有 其他研究 支持这一点)
话虽如此,可变字体可能对有阅读障碍的人有所帮助(所以请尝试使用!)。
您能详细说明“避免在视窗大小媒体查询中更改字体大小”吗?
D,如果您的类型随着视窗大小的变化而变化,当用户放大时,如果放大触发了媒体查询,类型将不会一致地缩放。在我的评论中的第一个链接中查看示例。
我通过媒体查询在桌面版上增加根字体大小。
这是一个问题吗?
我将那个 MQ 放到一个笔上,并将我的窗口最大化到 1,920 × 1,080。当我放大到 150% 时,文本变大了。当我放大到 175% 时,文本比 150% 放大时更小。在 200% 放大时,文本大小与 150% 放大时的文本大小相同。为了使文本达到原始大小的 200%,我必须放大到 250%。所以是的,这是一个问题。
我刚写了同样的内容,忽略了你的评论。对我来说它很有效,并且在以下文章中也推荐了它:https://betterwebtype.com/articles/2019/06/16/5-keys-to-accessible-web-typography/
我忘记提了,你应该对媒体查询断点使用 em。在那里,它们始终指的是浏览器的基础字体大小,而不是您可能对根元素设置的字体大小,否则您可能会陷入无限循环。
我最近开始做的事情是在
px
和rem
中都指定字体大小(假设基础字体大小为16px
)这种重复确实会稍微增加 CSS 文件的大小,但它允许您使用像素进行设计/编码(包括对该 px 大小的简单参考),快速转换为
rem
(如果您愿意,可以使用预处理器),并且如果浏览器不支持rem
会提供回退(诚然所有主流浏览器都支持,但我总是担心一些不太常用的设备——特别是辅助技术设备——可能不支持)。我喜欢在大型屏幕上通过更改根字体大小来放大整个网站,如果您在所有地方使用 rems 和 Ems(包括您的媒体查询),这可以正常工作。只要确保不要使用像素,而是使用百分比
html {
font-size: 110%;
}
这将考虑用户的字体大小,所以它可能是 16px 的 110%,或者可能是用户选择的任何大小。
嗨,Andrés,感谢分享 :)
一个小小的说明
默认情况下,iOS 不会根据用户设置对相对长度进行调整,除非您使用支持动态类型行为的系统字体。
要启用此功能,您可以将 -apple-system-body 定义为根字体(我使用 HTML 因为它比 :root 的特异性更低)