书名:包容性Web设计
ISBN:978-7-115-45818-6
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
• 著 [美] Heydon Pickering
译 于 坤
责任编辑 赵 轩
• 人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
• 读者服务热线:(010)81055410
反盗版热线:(010)81055315
前端开发者往往不自觉地就做出可访问性很差的网站,这不是粗心也不是能力问题,而是没有掌握正确的方法,且对当下多平台开发心存畏惧。
本书帮助 Web设计师、开发者和测试小组,创新性地从设计模式的角度思考可用性体验;帮助开发者破除迷思,澄清误解,以高效的方式制作可访问的界面。此外,本书还介绍了一些前端设计模式来创建包容性体验。
本书思路新颖,内容深入浅出,汇集了作者多年积累的宝贵经验,无论是工作多年的资深前端开发、测试工程师,还是刚入门的前端新人,都能从本书中得到启发。
Heydon Pickering 是一位实用主义设计师、作家和公众演说家,Smashing Magazine 的无障碍编辑,也是 Paciello Group的顾问。他对使用新的和创新型的方式让网络更具包容性很感兴趣。用户研究、系统思考和古老的语义化 HTML 各司其职。当他不写作、编码、画图时,会参与心理健康运动、声音设计实验,用他失真的电吉他弹奏金属摇滚。当然,也离不开啤酒。
Rodney Rehm 是一位住在德国南部的网站开发者,拥有10年的全栈开发经验,目前在 Deutsche Telekom 的智能家庭平台 Qivicon 做前端工作。他创建了URI.js和 ally.js,使 libsass 能在浏览器中运行,并写出了世界上第一个 buggyfill。 Steve Faulkner 是 TPG 欧洲的 Web 无障碍高级顾问和技术总监,于 2006 年加入 Paciello Group,之前是 Vision Australia 的网络无障碍高级顾问。他是 Web Accessibility Toolbar无障碍测试工具的创建者和首席开发者。Steve 是几个小组的成员,包括 W3C Web 平台工作组和 W3C ARIA 工作组。他还是W3C几个规范的编辑,包括:
HTML 5.1
ARIA in HTML
Notes on Using ARIA in HTML
HTML5: Techniques for useful text alternatives
HTML5accessibility.com 网站也是Steve负责开发和维护的。
刘彪是信息无障碍研究会的技术主管,他拥有丰富的信息无障碍实践经验,是中国屈指可数的信息无障碍专家。
加入信息无障碍研究会以来,刘彪为包括腾讯、阿里巴巴、百度、搜狗、滴滴等在内的众多知名公司的产品提供专业的信息无障碍相关服务。
刘彪精通计算机技术,拥有超过10年的C/C++、PHP经验,曾独立研发PC端屏幕阅读软件、构建面向障碍用户基于云的软件市场、创建并运营障碍群体辅助技术在线社区,他还参与了WCAG2.0中文版审阅。
假设我们在一个聚会上见面了,几句寒暄后,你问我是做什么的,“我是个设计师”我回答道。你还没有来得及问我是什么设计师,我们共同的朋友—聚会主人—拍我的手肘说:
“能占用你点时间吗?”
主人向你说了声抱歉后便带我离开了。你松了一口气,因为那种自豪地宣称自己是“设计师”的,很可能是一个很自负的人。尽管如此,你还是好奇我到底是做什么的。也许在设计杯子?缝制后现代主义的泳装?开发直升机导弹系统?可以指任何事情。
不过直到聚会结束,我们也没有机会重新认识。第二天与我们共同的朋友打电话时,他再次为前一天打断你致歉。过了一会儿,你回忆起来。
“哦,没关系。你的设计师朋友,具体设计什么?”
“呃,他是个 Web 设计师。”
“哦,这样啊。”
“是啊。”
现在,你的反应取决于你对庞大、模糊的公共信息母体(我们称之为Web)的关系。如果你只是互联网的消费者,而不是生产者,知道“Web 设计师”这个词就足够了:“哦,他设计网络上的东西,网站之类的。
我打赌你不是这类人,否则你不会读这本书。这时候你明白,在互联网行业中“设计师”一词多么有争议,甚至与经典设计术语的定义截然不同。所以哪些人是设计师,他们具体做什么?
很长一段时间以来,这个问题的答案都是严重错误的。“设计师”一词被误解,给从业者平添了不少麻烦。
我们这个行业最根深蒂固的错误就是,将印刷介质的视觉传达设计中的原理应用于Web。印刷设计师的领域纯粹是视觉的,局限于可预测的空间,使用商定好的材料,可以还原设计稿中的分辨率和颜色。印刷设计的成品是静态的,不能变。
显然 Web 不是这样的,但人们还是花费巨大的精力以期许毫无意义的像素级完美,还将我们从业者武断地划分为设计师和开发者,而没有考虑到还有内容编辑和项目经理!
实际上,设计师的工作应当深思熟虑、仔细斟酌,对给定的问题追求最佳解决方案。如果把设计仅仅局限于视觉美学,会让 Web 变得杂乱无章,更别提会导致网站无法访问、性能低下,当然实用性也会很差。
本书的目的是培养你的 Web 设计思维,并关注一些(令人惊讶的是最近才有的)Web 设计学科的发展。
网页是由代码组成的,因此,用代码设计才是用对了材料。这是最好的实践方案。
(我们通过网络写出来,或以其他方式表达出的)内容,必须遵循设计思维,事实上,所有其他设计决策都应该有助于实现这个目的。
网页不是一成不变的,应该支持变化的动态内容。这些内容应该用组件管理,组件可以用约定好的模式重复使用。
网站或 APP 的潜在受众是所有人,Web的包容能力、用户的偏好和使用环境是最重要的。受众不同(总是不同)时,包容性的界面才是最可靠的。
本书的主题和目的,最后也是重要的原则,在我们研究包容性模式之前,首先必须定义包容性设计。它更像是一种心态,而不是可以简化的技能,所以我要通过一个类比来说明。
以下的 JSON 代表了一个街道地址:
"address": "84, Beacon St, Boston, MA 02108,
United States”
现在如果我想使用像 Handlebars 这样的模板库,来打印地址到屏幕,我可能会这样写模板 {{this.address}}
,但是如果我需要用到地址中的国家怎么办?当前的数据形式是字符串,我必须写一个帮助函数取出“United States”这部分。
Handlebars.registerHelper(‘getCountry’, function(address) {
return address.split(',').pop();
});
这其实是一种 hack:一种脆弱又复杂的解决方法。出现了 hack 就是坏设计的征兆。使用辅助函数不仅计算量大,也不可靠,为什么?因为并非所有地址都以国家/地区结尾,例如英国地址通常以邮政编码结尾:
"address": "85-87, Gwydir St, Cambridge, England, CB1 2LG"
一个更健壮的解决方案是,让地址属性成为一个对象,并将地址的每个部分存储为该对象的一个属性:
"address": {
"building":"85-87",
"street":"Gwydir St",
"city":"Cambridge",
"country":"UK",
"zipOrPostcode":"CB1 2LG"
}
现在我们可以简单地用 address.county
取得国家。
这似乎是一个更好的方法,但真的是这样吗?使用一个巨大的国际地址集合,你会发现它们区别太大,不可能规定一个固定的属性集。简单地截取字符串更合适一些,但有时候也不能获取到国家。
无论如何,考虑数据结构试图获得一个最佳解决方案就是设计。不需要买 Adobe 软件,也不用 Sketch。实际上这就是一种包容性设计:正确的解决方案是包容各种不同类型的地址。我们希望能处理一致、统一的地址,但这不现实,所以我们也考虑例外情况。
上一段的句子中,用“界面”替换掉“数据的结构”,用“人”替换掉“地址”,你就理解包容性设计了。
最棒的就是,设计包容性的界面就像设计健壮的数据结构一样,没有变得更难、更复杂,只是不一样而已。本书将通过包容性的透镜查看常见的Web 界面,帮你快速了解如何运用和重复运用包容性设计的约定,从而给你带来更广泛、更忠实的受众群体。
来看一个更简单的例子,一个界面模式的原型很像这样,我们从3种类型的设计师角度看待一个交互元素——按钮。这个例子的目的是向你展示:多了解一点这方面的知识,就可以做出更简单、更具包容性的方案。
第一个设计师有平面设计背景。他们的文件从来没有低于 300dpi,他们懂得颜色理论,排版作图的技巧能力也很强。对他们来说,按钮是一个视觉工艺品,可以在 Adobe Illustrator 或 Sketch 中制作。他们关心的是,如何将这个按钮做得像一个真正的按钮,同时还要适应品牌。他们不知道如何把这个按钮放到网页上或者让按钮做其他动作。
第二个设计师会很多和第一个设计师一样的技能,但在一个重要的方面不同:他有充足的 HTML、CSS 和 JavaScript 知识,能把按钮放到网页中,并附加一个 JavaScript 监听事件。
HTML 结构看起来是这样的:
<div class="button"></div>
CSS是这样的:
.button {
width: 200px;
height: 70px;
background: url('../images/button.png');
}
JavaScript 可能是用 jQuery 或者 Angular JS API 写的,也可能是用 Web API(原生 Javascript),可能看起来是这样的:
button.addEventListener('click', function() {
// the event fired on click
});
虽然被称为设计师,但是他已经学会了编码,可以把想法放到 Web ——把它们放到网页中,甚至某些功能对小部分用户还可用。但不幸的是,除了监听事件,他们真正做的是编码还原视觉设计,而不是用代码设计。第三个设计师已经意识到这点,平面设计和 Web 界面设计几乎没有直接的转换关系。
第三个设计师从多个角度看待第二个设计师的按钮,每一点都是站在一个潜在用户的角度,能看到当前做法导致的许多问题。
一个问题是,缩放网页以方便阅读的用户不少,但如果用户整页缩放,而网页中的图片又不是矢量图,那就无法做到缩放不失真。如果用户只调整了浏览器的默认字体大小,则图片(因为使用的是像素单位而不是相对单位)将不会缩放。
另外一个问题是,当用户使用移动网络,关闭图像以节省流量时,完全由背景图像构成的按钮将不可见。用户打开高对比度模式的时候,有时候很难区分前景和背景图像,在某些情况下,也会看不到背景图。
不止于此,<div>元素跟内建的 <button> 元素不同,它在当前的表单中没有获取焦点或者由键盘操作的能力。有些人喜欢用键盘导航和操作网页。有些人却只能用键盘,因为鼠标需要更精细的手指动作控制,他们做不到。
屏幕阅读器用户、视力严重受损的人,还有通过使用合成语音读出网页以辅助理解的人,他们的访问能力都被剥夺了。大多数桌面屏幕阅读器用户也是键盘用户,所以他们会遇到同样的问题,此外 <div> 没有语义含义,不能提供非视觉的按钮信息。
由于按钮的“Start”文字在背景图像中,(为残疾人设计的)辅助技术也无法起作用。同样的原因,按钮也不能被翻译成其他语言,它也限制了国际受众,错失了很多用户。
包容性设计师会预知这些问题,因为经验告诉他们;用户不同,访问方式也不一样。但他们不会气馁、沮丧,因为他们知道怎样利用标准惯例,用更少的工作实现更多目标。换句话说,他们知道什么时候需要设计,什么时候使用已有的一个简单的 HTML 按钮元素,作为 HTML规 范的标准元素。可调整大小、可翻译、可聚焦、可交互、可定制样式、可以覆盖样式、可维护、可变化、简单。
<button>Start</button>
不是所有的包容性设计方案都像这样,选择正确的 HTML 元素就能解决。即便如此,把简单的标准元素和常规的结构组合起来同样也不困难,也不破坏艺术气息,<button> 元素可以由近乎无限多种方式呈现。
“16进制有 140737479966720 种组合,当然不是所有的都能访问,如果有 1% 的颜色组合可以使用,总共有大约 1.41 亿个组合可供选择。完全超出你的职业生涯所需了 ”
—— Adam Morse
随着经验的积累,为界面设计的包容性问题找出无尽的解决方案,可以成为第二天性。本书中描述的模式可作为示例,但大多数用于练习。当新的问题出现时,需要定制不同的包容模式时,你应该已经学会如何定制模式。你将成为一个具有包容性的设计师。
虽然本书的其他章节会分别讨论界面的模式,也就是我们常说的模块或组件,但是这些模块最终都属于一个 Web 文档。HTML 页面在形式和大小上差别很大,并且可以包含任意模式的组合。在文档级别,有几个最佳实践应该遵守。
本章的目的不是去寻找终极的样板,而是为包容性的界面配置父级 Web 页面。
无论你的网页是经典的静态资源还是单页应用,都必然是一个文档。证据就是代码第一行的“DOC”部分:<!DOCTYPE html>
。这是一个重要的提醒,即使你设计一个手感极佳的动态界面,仍然只是把内容放在浏览器窗口。不要忘记,浏览器本身也是一个界面,可以被用户以多种方式扩展和配置,还有第三方提供的帮助解释网页内容的技术,如屏幕阅读器。你的辅助界面也需要包容用户的不同设定和配置。
用户打开浏览器时,你的界面不是唯一的交互界面。
此外,省略上述的文档类型标签(Doctype)可能会导致意外甚至更糟糕的情况。如果没有声明文档类型,浏览器根本不知道该如何解释内容,可能会降级到不符合规范的兼容模式,即通常所说的怪异模式(quirks mode)。此时布局和交互就会变得不可预知,很容易出错。如果我正在测试的网页变得很奇怪,我会首先检查一下文档类型 。我被坑太多次了。
如果说文档类型是在告诉浏览器正在处理什么类型的文档(上文中是 HTML5),那么 <html>
标签的lang
属性就是在告诉浏览器用的是哪种语言。
我不是说 HTML 或者 XHTML 这种语言,而是指英语或者法语。
<html lang="en"> <!-- 语言设置为英语 —>
虽然声明网页语言总是被忽略,但几乎没有比这个更重要的事了。它不仅使网页更容易被搜索引擎索引,而且更容易被谷歌翻译接口这样的第三方工具翻译,还有助于用户在网页中书写,如 Firefox 会调整 <textarea>
中的字典,以便正确地标注拼写错误。
更明显的是,如果页面没有声明语言或者声明错误,使用屏幕阅读器时不会触发正确的语音配置。也就是说,如果设置了 <html lang="en">
但是文字内容是法语,你会听到一个糟糕法语的 Jack 发音,而不是正宗法语发音 Jaques 。
<p>Il ne faut pas mettre tout dans le même sac!</p>
正确的语言声明除了让屏幕阅读器和盲文显示器受益,它还帮助浏览器选择恰当的系统字体。例如 lang="zh-Hans"
将调用简体中文字体渲染。如果让用户看到乱码或者不合适的字体,就不算是好的包容性设计。
也可以在<body>
的子元素上指定 lang
属性切换页面内的语言。例如,我可能想在英语语言的页面中引用一些法语:
<blockquote lang="fr">
<p>Ceci n’est pas une pipe</p>
<p>— <cite>René Magritte</cite></p>
</blockquote>
在 CSS 中,也可以使用 :lang
伪类来选择对应的法语内容,使用适合法语的字体能够提高可读性:
:lang(fr) {
font-family: French Font, fallback, sans-serif;
}
lang
属性可以提高 Web 文档中书面内容的可读性、可翻译性和兼容性,有助于开拓国际用户。声明lang
属性很容易,赶快加上吧。
响应式设计是包容性设计的重要组成部分。将文档设计成可以响应和自适应所处环境,能做到与市场上不断增长的设备兼容。本书不讨论响应式设计的内容,但你应该知道响应式设计中一些有助于实现包容性设计的原则。
如果想创造一个真正的包容性体验,针对特定的视口(viewport)使用设备断点(device breakpoints)只会徒劳无功,因为有太多视口需要适配了。相反,你应该从一开始就采用灵活的设计,只在内容破坏布局时创建断点,也就是说内容断点(content breakpoint)或调整点(tweak point)。
通过内容断点,可以保证布局能适应数量远大于你能测试到的设备。如果你没有预知未来的超能力,可以预测到每个用户使用的设备,那么这便是唯一的方法了。
使用 Firefox 的响应式设计模式,可以很容易找到内容断点。只需要按下 Cmd + Option + M,然后逐步调整模拟视口的大小,直到内容发生碰撞、折叠或者换行,记录下此时界面上显示的尺寸作为断点以备处理。
你的响应式设计应该涵盖各种宽度,但是这不意味着你要为每个宽度设置断点。
简单的界面即是可用的界面,处理断点的工作也会少很多。根据经验,不应该在任何元素上设置固定的宽度或高度:盒子的内在灵活性意味着同样的内容可以适应不同空间。没有指定 CSS 的网页就是这样,有 CSS 的时候也应该遵守这种基本行为。
使用视口(viewport
)meta 标签就能方便地开启响应式设计。然而我们习惯性地禁止用户缩放,让这种体验不那么顺畅了。在一次非正式的调查中,我问 我的粉丝们,设计师在包容性方面犯的最大错误是什么,迄今为止,被提到最多的就是手持设备上禁止手指缩放。
再明确点说,下面第一个是不可接受的;第二个是正确的。
<!-- 不要这样用 -->
<meta name="viewport" content="width=device-width, initial- scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- 用这个 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Adrian Roselli 给出了一个完整的列表,说明为什么禁用此功能会破坏包容性。
文字可能太小,用户无法阅读。
用户可能希望看到更多图片细节。
文本较大时,用户更容易选择要复制、粘贴的字词。
用户想把动画元素移到视图外,以减少分心。
开发人员的响应式设计做得不好,用户需要缩放才能使用页面(的确会发生!)。
浏览器有 bug 或者出现怪异模式(也是bug),导致默认缩放级别很奇怪。
当双指捏合、张开的动作用于其他功能时,可能会让用户混淆。
你可能还记得我之前说的,浏览器本身也是一个界面。要实现包容性的设计,你应该充当协调者,允许用户看你的内容时,自己定义视图和查看方式。你做的决定越少,用户可以做的决定就越多。
如果在缩放布局时发生错误,这是设计师的错,而不是用户的错。并且一味地禁用缩放功能不是解决方案。根据经验,应避免使用定位元素,特别是position:fixed
。将内容放大时,粘附到屏幕的某一部分的任何元素都有可能变成盲点。
默认情况下,桌面浏览器将字体渲染为 16 像素,这是有原因的:其他的值可能会让很大一群人不舒服,比如很多视力不好的年长用户。你可能会说“我的用户年轻又时髦啊!”但是使用大一点的字号并不会冒犯视力好的年轻人。包容性设计的关键不是针对特定群体,而是不武断地排除特殊群体。
你可能已经习惯了在根元素(<html>
)上设置百分比字体,如下所示:
html {
font-size: 100%;
}
在这个例子中,如果用户尚未在操作系统或浏览器设置里(例如,Firefox中的【首选项】→【内容】)手动调整字体大小,则 100%
等于 16px
。所以 100%
就是“百分之百的默认大小或用户选择的大小”。如果我们在根元素级别将字体大小显式设置为 16px ,用户根据喜好调整字体大小的功能就丢失了。
html {
/*不要这样做*/
font-size:16px;
}
的确,大多数用户使用 Cmd(或Ctrl)和+缩放网页,但是现代浏览器和操作系统仍支持只调整文本大小。所以为了确保字体大小、padding
和 margin
都同比例调整,设计师应该使用 rem
或 em
等相对单位。
这能大大降低媒体查询的复杂性。在下面的示例中,行高和p
的边距会同比例缩放,因为它们都是相对于字体大小设置的。在一切都以同比例设置的情况下,可以通过调整根字体的大小来缩放整个页面,如下面的媒体查询。
注意:为了确保媒体查询根据字体大小正确触发,我们也使用 em 单位。rem 单位在 Safari 中会出问题。
p{
margin: 1.5rem 0;
font-size: 1rem;
line-height: 1.5;
}
@media (max-width: 60em) {
html {
font-size: 80%;
}
}
一个 <h2>
给定 font-size:2em;
就是根字体大小的两倍。如果用户已经在 Firefox 的【设置】 →【内容】里将默认字体大小设置为 20px,则 2rem
将意味着 2 × 20 也就是 40px。不要错误地用 CSS 预处理器将理论的 rem 单位转换为像素单位。最终编译的 CSS 也要考虑浏览器解析的情况。
视口单位提供了设置文字随着视口的高度(vh)或宽度(vw)缩放的机会。这意味着你可以使用隐式的响应式文本,不需要前面示例代码中的媒体查询。
译注:
1vw = 1% 的视口宽度
1vh = 1% 的视口高度
1vmin = 1vw 或 1vh, 取较小的值
1vmax = 1vw 或 1vh, 取较大的值
只有一个问题需要解决:使用视口单位的元素,无法随着页面缩放。为此,可以将视口单位的值加上 em 单位的值恢复缩放功能,这样就能确保页面有最小字体尺寸。原理就是: 1em + (0×1vw)
仍然是1em
。
html { font-size: calc(1em + 1vw); }
有了这个算法,所有内容都会逐渐地随着视口同比例缩放。节省了大量的手动编码,又不牺牲可访问性。
写作本文时,唯一不支持视口单位的现代浏览器就是 Opera Mini。不过不用担心,font-size: calc(1em + 1vw);
是渐进增强的。无法识别的时候,浏览器会回退到浏览器默认设置。也就是说,Opera Mini 会用原定的方式展示文本。
渐进增强跟响应式设计一样,是包容性设计的基石。花费力气保证用户在关闭 JavaScript 的时候 Web 应用仍然可用,这种做法有很大的争议,但是渐进增强有更深远的意义。
为内容建立一个强大的基础,逻辑合理、结构健壮,能适应多种网络或脚本失败的情况。不单是 JavaScript 或 CSS 不可用,还包括何时、怎样、多长时间不可用,何时应该可用以及用什么顺序可用,都属于渐进增强。
本书中的模式基于良好语义化的 HTML 结构,用 CSS 和 JavaScript 增强。在可以的情况下,集成的 JavaScript 小部件降级为结构良好的静态内容或交互表单。这意味着没有 JavaScript 或 CSS —— 不管是暂时的还是永久的——都可以看到并使用内容。无论 JavaScript 是否可用,语义化的 HTML 都可以给使用辅助技术的用户以包容性的体验,也会让交互行为更容易预测,更高效。
增强是好事,但是只在真正需要的地方。
在渐进增强体系中,脚本应插入到文档末尾,紧邻 </body>
结束标签之前,这样会让 DOM 内容在脚本执行之前渲染。
<script>// TODO: 增强内容</script>
</body>
在文档设置方面,确保增强内容不会阻碍页面内容的加载,这非常重要。在条件不佳的网络中,内容应该尽快到达,毕竟用户是为内容而来。
Web 字体通常都是大型的资源,应该被视为增强内容。特别是FOIT(Flash of Invisible Text,不可见字体闪现)应该避免:如果字体文件无限加载(确实会发生),用户的设备或者浏览器就会卡在没有文字的页面。这对不稳定的网络非常没有包容性。
诀窍是,加载页面后再加载字体,用 onload
事件触发。要想实现这个效果,字体必须用 base64 编码嵌入到样式表中。在 Keith Clark 的例子中,<link>
有一个 onload
处理程序,将 media 类型从 none
改为all
。如果 JavaScript 完全不可用,可以用 <noscript>
标签直接加载 CSS。
<link rel="stylesheet" href="fonts.css" media="none"
onload="if(media!='all')media='all'">
<noscript><link rel="stylesheet" href="fonts.css">
</noscript>
base64 编码的字体将包含在 @font-face
声明中,如下所示:
@font-face {
font-family: Merriweather;
font-style: normal;
font-weight: 400;
src: local('Merriweather'),
url('data:application/x-font-woff;charset=utf-8;base64...');
}
解决 FOIT 更全面的方法是由 Bram Stein提供的,需要一小段 JavaScript 依赖。Font Face Observer 使用简单的 promise 接口监视并等待字体加载完成:
var observer = new FontFaceObserver('MyWebSerif');
observer.check().then(function() {
document.documentElement.className += "fonts-loaded";
});
然后用上面显示的 .fonts-loaded
类展示 CSS 中的字体:
html {
/* 系统字体和备用字体 */
font-family: MySystemSerif, serif;
}
html.fonts-loaded {
/* Web 字体和备用字体 */
font-family: MyWebSerif, MySystemSerif, serif;
}
为了战胜 FOIT,必须接受一个小的弊端,就是 FOUT(Flash Of Unstyled Text,无样式字体闪烁)。这是个不太公平的绰号,因为所有字体都有定义样式。但是当 Web 字体加载完成后替换系统字体时,可能会有一个不愉快的跳动。这是因为两种字体大小可能不同而导致间距不一样。
为减轻这种不良影响,最好的策略是选择与 Web 字体类似的系统备用字体。
支持大量国际字符的字体是包容性的字体,但只包含所需字符的子集就更好了,否则用户可能会遇到性能问题。一个完整的字体和一个只包含 & 字符的子集,在文件大小上有数量级的差异。
使用 Google 字体时,可以在 URI 中附加text
参数,只列出你需要的字符。例如,如果你确定 <h2>
标题只会用到一种字体的大写字母的话,可以使用下面的链接:
<link href="https://fonts.googleapis.com/
css?family=Roboto:900&text=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
rel="stylesheet" type="text/css">
如果你的字体放在自己服务器,可以先用 Font Squirrel 的工具处理一下。CSS 字体列表中,首选字体中不存在的字符,会用后面的替代字体渲染。在实际应用中,用类似的系统字体替代不常用的字符,能大大减少Web字体数量。
通过使用 Font Squirrel 的工具,可以将 Web 字体的字符集精简到只包含基本的拉丁语编码( Basic Latin),例如:
body {
font-family: SubsettedWebFont, ExtensiveSystemFont,sans-serif;
}
<head>
元素中的 <title>
元素你应该已经很熟悉了,浏览器提取这里的文字作为网页标签名字,搜索引擎用它作为结果链接的名字。没有标题的标签页对用户有点不方便,尤其是对使用辅助技术的用户有更大的影响。本书会多次提到可访问的名称。这种与辅助技术兼容,用来描述元素的目的和内容的标签,很多网页元素都会用到,如文档、<iframe>
或者内嵌的 SVG 元素都有自己的 <title>
作为可访问的名称。
文档加载后会立即展示 <title>
,这是提供页面简明摘要的好地方,一般做法是描述页面并附加作者和网站信息。
例如“包容性设计模板 | Heydon 的网站”,搜索结果页应该包含用户搜索的词;例如“网站名称 | xxx的搜索结果”。
本书中的某些模块如导航区域,应该像地标一样在页面之间一直显示。剩下的构成网页独特性的模块,通常是动态生成的内容,在常规的页面中都会放到主内容区域。
<main id ="main">
<!-- 此网页的独特内容 -->
</main>
主内容不是一个新的概念,但是最近我们有了新的工具将它与其他内容,如页头(header)、导航(navigation)和页脚(footer)区分开来。<main>
元素定义了可以被屏幕阅读器识别并进行沟通的区域。像 JAWS 这样的阅读器还提供了一个快捷键(Q键)来访问 <main>
,让用户跳过前面的部分而直达内容。在单页应用程序中,唯一的 <main>
应该是最重要的功能视图;在静态博客或者宣传网站中 <main>
应该包含博客文章和宣传内容;产品页面应该在 <main>
中描述产品。
因为 <main>
被设计为包含重要的内容,所以它可以让打印样式表更容易写。假设导航、页头、页脚和边栏(<main>
)都正确设置,都是 <main>
的兄弟元素,你可以使用CSS轻松搞定:
@media print {
body > *:not(main) {
display: none;
}
}
我不是那种会打印网页的人。很久以前我就放弃了家用打印机,因为经常用10分钟它就坏掉,但不是每个人都像我一样。用户打印页面时,如果你能周到地去除仅在屏幕上浏览才有用的页面元素,也是一种包容性的设计。用户可以打印到 PDF 并保存到本地,这是目前最简单的离线解决方案了。
去掉辅助内容的另外一个好处是,可以提升屏幕上的阅读体验。
跳过链接是典型的以包容性的名义做的设计:虽然它的用处看似不大,但它们对某些用户体验的影响已经显现。
跳过链接显示在页面上所有其他内容的最上面,指向主要内容区域。是为谁做的呢?一般认为是为了屏幕阅读器用户,但是就像我已经提到的,这些用户有其他手段到达 <main>
元素。跳过链接最主要的受益者是键盘用户,这些人没有与屏幕阅读器用户一样的快捷方式,所以我们基本上都是在帮助他们跳过导航和其他顶部内容。
跳过链接不需要默认显示,因为它们对鼠标和触摸屏用户没什么帮助,这只会让他们迷惑。要使键盘用户知道这个链接,它就应该在获得焦点时显示出来:
[href=”#main”] {
position: absolute;
top: 0;
right: 100%; /* 移出屏幕 */
}
[href=”#main”]:focus {
right: auto;
}
当键盘用户进入新页面时,文档本身是第一个接受焦点。用户按Tab 键时,会让第一个元素,也就是这个跳过链接获得焦点,然后被显示出来。给用户提供跳到主要内容的选项(如果需要的话)。再次按Tab 键,焦点会移到下一个元素上,可能是主页链接或者导航列表中的第一个元素。跳过链接失去焦点就会隐藏。
好了,让我们看看我们的包容性的文档的最终形态:
<!DOCTYPE html>
<!-- the main language of the page declared -->
<html lang="en">
<head>
<meta charset="utf-8">
<!-- a viewport declaration which does not disable zooming -->
<meta name="viewport" content="width=device-width,
initialscale=1.0">
<!-- a non-blocking base64-encoded font resource -->
<link rel="stylesheet" href="fonts.css" media="none"
onload="if(media!=’all’)media='all'">
<noscript><link rel="stylesheet" href="fonts.css"></noscript>
<!-- a non-blocking stylesheet -->
<link rel="stylesheet" href="main.css" media="none"
onload="if(media!='all')media='all'">
<noscript><link rel="stylesheet" href="main.css"></noscript>
<!-- a descriptive label for the page -->
<title>Inclusive Design Template | Heydon's Site</title>
</head>
<body>
<!-- a handy skip link for keyboard users -->
<a href="#main">skip to main content
<!-- logo / page navigation etc. goes here -->
<main id="main">
<!-- unique content of page goes here -->
</main>
<!-- a non-blocking javascript resource -->
<script src="scripts.js"></script>
</body>
</html>
对我来说,开发人员的人类工程学没有用户的需求重要。
—— Paul Lewis
很多网页设计文章和书籍都专注于改善你的工作流程,让开发人员生活更轻松。如果你希望用框架或者预处理器来加快开发过程,请便。然而这本书的目标不是你,而是你的受众。
因此,只有在对用户体验质量有直接影响的情况下,才花时间在工具上。所有其他情况,我们都会花时间在探索标准 Web 技术,如 HTML、CSS、JavaScript 和 SVG 提供的可能性上,探讨这些底层技术如何与你的用户实现互动才是本书的重点(当然组织文案和写作技巧也有利于用户)。
在这里学到的经验,你可以灵活运用到任何框架,写出和组织良好的界面。
任何不容易实现包容性设计的框架都应该放弃使用,它们只会让你做出劣质产品。
为了专注于手头真正的任务,我有一个积分系统。在任何情况下,无论我在实 现视觉设计、写 JavaScript 或组织内容结构,我都会问, 我的作为会让谁受益。
100 分是我们的目标。