包容性Web设计

978-7-115-45818-6
作者: 【美】Heydon Pickering
译者: 于坤
编辑: 赵轩

图书目录:

详情

本书介绍了“可访问性思维”涉及的方法论以及根本原则,并创建了一系列有代表性的用户角色,之后用较大篇幅系统地逐次介绍设计的具体原则及其在实战中的使用建议。这是一本web设计的最佳实践总结,可以解决行业人员的疑惑与误区

图书摘要

版权信息

书名:包容性Web设计

ISBN:978-7-115-45818-6

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

• 著    [美] Heydon Pickering

  译    于 坤

  责任编辑 赵 轩

• 人民邮电出版社出版发行  北京市丰台区成寿寺路11号

  邮编 100164  电子邮件 315@ptpress.com.cn

  网址 http://www.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几个规范的编辑,包括:

HTML5accessibility.com 网站也是Steve负责开发和维护的。


刘彪是信息无障碍研究会的技术主管,他拥有丰富的信息无障碍实践经验,是中国屈指可数的信息无障碍专家。

加入信息无障碍研究会以来,刘彪为包括腾讯、阿里巴巴、百度、搜狗、滴滴等在内的众多知名公司的产品提供专业的信息无障碍相关服务。

刘彪精通计算机技术,拥有超过10年的C/C++、PHP经验,曾独立研发PC端屏幕阅读软件、构建面向障碍用户基于云的软件市场、创建并运营障碍群体辅助技术在线社区,他还参与了WCAG2.0中文版审阅。


假设我们在一个聚会上见面了,几句寒暄后,你问我是做什么的,“我是个设计师”我回答道。你还没有来得及问我是什么设计师,我们共同的朋友—聚会主人—拍我的手肘说:

“能占用你点时间吗?”

主人向你说了声抱歉后便带我离开了。你松了一口气,因为那种自豪地宣称自己是“设计师”的,很可能是一个很自负的人。尽管如此,你还是好奇我到底是做什么的。也许在设计杯子?缝制后现代主义的泳装?开发直升机导弹系统?可以指任何事情。

不过直到聚会结束,我们也没有机会重新认识。第二天与我们共同的朋友打电话时,他再次为前一天打断你致歉。过了一会儿,你回忆起来。

“哦,没关系。你的设计师朋友,具体设计什么?”

“呃,他是个 Web 设计师。”

“哦,这样啊。”

“是啊。”

现在,你的反应取决于你对庞大、模糊的公共信息母体(我们称之为Web)的关系。如果你只是互联网的消费者,而不是生产者,知道“Web 设计师”这个词就足够了:“哦,他设计网络上的东西,网站之类的。

我打赌你不是这类人,否则你不会读这本书。这时候你明白,在互联网行业中“设计师”一词多么有争议,甚至与经典设计术语的定义截然不同。所以哪些人是设计师,他们具体做什么?

很长一段时间以来,这个问题的答案都是严重错误的。“设计师”一词被误解,给从业者平添了不少麻烦。

我们这个行业最根深蒂固的错误就是,将印刷介质的视觉传达设计中的原理应用于Web。印刷设计师的领域纯粹是视觉的,局限于可预测的空间,使用商定好的材料,可以还原设计稿中的分辨率和颜色。印刷设计的成品是静态的,不能变。

显然 Web 不是这样的,但人们还是花费巨大的精力以期许毫无意义的像素级完美,还将我们从业者武断地划分为设计师和开发者,而没有考虑到还有内容编辑和项目经理!

实际上,设计师的工作应当深思熟虑、仔细斟酌,对给定的问题追求最佳解决方案。如果把设计仅仅局限于视觉美学,会让 Web 变得杂乱无章,更别提会导致网站无法访问、性能低下,当然实用性也会很差。

本书的目的是培养你的 Web 设计思维,并关注一些(令人惊讶的是最近才有的)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 给出了一个完整的列表,说明为什么禁用此功能会破坏包容性。

你可能还记得我之前说的,浏览器本身也是一个界面。要实现包容性的设计,你应该充当协调者,允许用户看你的内容时,自己定义视图和查看方式。你做的决定越少,用户可以做的决定就越多。

如果在缩放布局时发生错误,这是设计师的错,而不是用户的错。并且一味地禁用缩放功能不是解决方案。根据经验,应避免使用定位元素,特别是position:fixed。将内容放大时,粘附到屏幕的某一部分的任何元素都有可能变成盲点。

默认情况下,桌面浏览器将字体渲染为 16 像素,这是有原因的:其他的值可能会让很大一群人不舒服,比如很多视力不好的年长用户。你可能会说“我的用户年轻又时髦啊!”但是使用大一点的字号并不会冒犯视力好的年轻人。包容性设计的关键不是针对特定群体,而是不武断地排除特殊群体。

你可能已经习惯了在根元素(<html>)上设置百分比字体,如下所示:

html {
   font-size: 100%;
}

在这个例子中,如果用户尚未在操作系统或浏览器设置里(例如,Firefox中的【首选项】→【内容】)手动调整字体大小,则 100% 等于 16px。所以 100% 就是“百分之百的默认大小或用户选择的大小”。如果我们在根元素级别将字体大小显式设置为 16px ,用户根据喜好调整字体大小的功能就丢失了。

html {
    /*不要这样做*/
    font-size:16px;
}

的确,大多数用户使用 Cmd(或Ctrl)和+缩放网页,但是现代浏览器和操作系统仍支持只调整文本大小。所以为了确保字体大小、paddingmargin 都同比例调整,设计师应该使用 remem 等相对单位。

这能大大降低媒体查询的复杂性。在下面的示例中,行高和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 分是我们的目标。


相关图书

TypeScript全栈开发
TypeScript全栈开发
Java EE企业级应用开发实战(Spring Boot+Vue+Element)
Java EE企业级应用开发实战(Spring Boot+Vue+Element)
Vue.js全平台前端实战
Vue.js全平台前端实战
Flutter内核源码剖析
Flutter内核源码剖析
智能前端技术与实践
智能前端技术与实践
从0到1:ES6快速上手
从0到1:ES6快速上手

相关文章

相关课程