我只用一个键盘就用了一天的网络
已发表: 2022-03-10这篇文章是我尝试在各种限制下使用网络的系列文章的一部分,代表给定的用户群体。 我希望提高真实人们面临的困难的形象,如果我们以一种同情他们需求的方式进行设计和开发,这些困难是可以避免的。 上次,我在没有 JavaScript 的情况下使用了一天的网络。 今天,我强迫自己只用键盘浏览网页。
谁使用键盘导航?
从广义上讲,键盘用户分为三种类型:
- 难以使用鼠标的行动不便的用户,
- 无法在页面中看到可点击元素的视力受损用户,
- 能够使用鼠标但发现使用键盘更快的高级用户。
我们在谈论多少用户?
我在网上搜寻了有关键盘使用情况的统计信息,但找不到任何东西。 严重地。 没有一项研究。
大多数键盘可访问性指南网站都理所当然地认为“许多用户”依赖键盘来四处走动。 任何试图获得一个大概数字的人通常都会以“统计数据无关紧要——你的网站应该是可访问的,期间”这样的说法被大肆驳斥。
是的,非鼠标使用的规模确实是一个有争议的问题。 如果您可以做出改变,甚至可以授权一个用户,那么这是一个值得做出的改变。 但是有很多关于色盲、浏览器使用情况、连接速度等方面的统计数据——为什么围绕键盘统计数据如此谨慎? 如果这些数字像网站所暗示的那样普遍,那么拥有它们肯定会带来更强大的业务案例,并使您的利益相关者更容易保护键盘可访问性。
我能找到的最接近数字的是 PowerMapper 上的一篇文章,该文章表明美国、英国和加拿大 7% 的工作年龄成年人有“严重的灵活性困难”。 这将使他们“不太可能使用鼠标,而是依赖键盘”。
有严重视觉障碍的用户使用称为屏幕阅读器的软件,该软件将屏幕上的内容作为合成语音读出。 与有视力的用户一样,无视力的用户希望能够扫描页面以获取有趣的信息,因此屏幕阅读器具有用于通过标题和链接导航的键盘快捷键,并依赖于键盘可聚焦元素进行交互。
“盲人需要全键盘访问。 时期。”
— David Macdonald,在 HTML5 中使用 WAI ARIA 的联合编辑
这些相同的用户在他们的移动设备上也有屏幕阅读器,他们使用滑动手势而不是键盘按下来“浏览”内容。 因此,虽然他们并没有真正使用键盘,但他们确实要求网站可以通过键盘访问,因为屏幕阅读器技术与相同的选项卡顺序和事件侦听器挂钩,就像他们使用键盘一样。 值得注意的是,只有大约三分之二到四分之三的屏幕阅读器用户是盲人,这意味着其余的可能会使用屏幕阅读器和放大技术的组合。
2.3% 的美国人(所有年龄段)有视觉障碍,并非所有这些都必然需要使用屏幕阅读器。 2016 年,Addy Osmani 估计屏幕阅读器的实际使用率约为 1% 到 2%。 如果我们将这些用户与我们的行动不便用户和我们的高级用户一起考虑,那么键盘使用在全球受众中占相当大的比例。 因此,关心键盘可访问性不仅是在道德上做正确的事(而且在法律上——许多国家要求网站必须依法可访问),而且还具有良好的商业意义。
考虑到所有这些,今天的网络状况如何? 是时候找出答案了!
本实验
当他们面临着一天令人生畏的工作时,每个人都在做什么? 拖延! 我前往 youtube.com。 我想到了一个特定的视频,并且很高兴发现我不需要进入主搜索框,因为它默认专注于页面加载。
autofocus
属性
我认为这将集中在窗口加载上的 JavaScript,但它实际上是由浏览器处理的,输入元素上有一个autofocus
属性。
作为一个有视力的键盘用户,我发现这非常有用。 作为盲人屏幕阅读器用户,我不确定我是否喜欢它。 共识似乎是明智地使用autofocus
是可以的,在页面的唯一目的是与表单交互的情况下(例如谷歌登录页面或站点联系表单)。
默认焦点样式
我搜索了一些这到底是谁的线路? 天哪,并且不禁注意到 YouTube 没有定义任何自定义:focus
样式,而是依靠浏览器的本机样式来直观地指示我正在浏览哪些元素。
我一直认为并非所有浏览器都定义自己的:focus
状态,因此您必须定义自己的自定义样式。 我决定对此进行测试,看看哪些浏览器忽略了实现默认样式,但令我惊讶的是,我找不到。 我测试的每个浏览器都有自己的:focus
本地实现,尽管每个浏览器的风格各不相同。
我什至可以追溯到很久以前:
如果您想了解更多,这里有浏览器原生状态下不同元素的综合截图集合。
这告诉我的是,您可以合理地假设每个浏览器都带有一些基本的:focus
样式。 让浏览器完成工作是可以的。 您所冒的风险是不一致:所有浏览器对元素的样式都略有不同,有些非常微妙,以至于它们在视觉上并不特别容易访问。
可以通过在元素上设置outline: none
来禁用默认的浏览器焦点样式,但只有在实现自己的样式替代方案时才应该这样做。 Heydon Pickering 推荐这种方法,理由是某些浏览器使用的默认值不明确或丑陋。 如果您决定推出自己的样式,请确保使用的不仅仅是颜色作为修饰符:添加轮廓或下划线或其他一些视觉指示器,以支持色盲用户。
许多网站禁止默认焦点样式但无法提供自定义样式,从而导致无法访问的体验。 如果您的网站使用 Eric Meyer 的 CSS 重置,则可能无法访问; 这个常用的文件会重置默认的:focus
样式,但会指示开发人员编写自己的样式,并且许多人没有发现这些说明。
有些人认为,如果您禁用浏览器默认设置,用户可能会感到困惑,因为他们失去了他们习惯的焦点状态的视觉可见性,而是必须了解您网站的焦点状态是什么样的。 另一方面,一些人认为浏览器的默认设置很难看,甚至会让非键盘用户感到困惑。
为什么会混淆? 好吧,看看 BBC 上的这种动画轮播格式。 有两个导航按钮——下一个和上一个——对于键盘用户来说,在整个叙述过程中焦点始终保持在它们上是很有用的。 但是对于鼠标用户来说,在将光标移开后单击的按钮仍然“聚焦”可能会非常令人困惑。
:focus-visible
CSS 选择器
如果你想要两全其美,你可能想探索 CSS4 :focus-visible
伪类,它可以让你根据上下文提供不同的焦点样式。 :focus-visible
样式仅针对已通过键盘而不是鼠标单击的元素。 这非常酷,虽然目前仅在 Firefox 中原生支持。 它可以通过打开“实验性 Web 平台功能”标志在 Chrome 中启用。
YouTube 视频和键盘辅助功能
YouTube 的视频播放器做得很好——播放器的每个部分都可以通过键盘导航。 我喜欢当您将焦点从静音图标上移开时音量控件如何滑出,而不是在将鼠标悬停在静音图标上时滑出。
我不喜欢的是有用的标签,例如悬停在静音图标上时出现的“静音”文本,不会显示在焦点上。
另一个让 YouTube 失望的地方是它抑制了一些焦点样式。 这是我试图点击“显示更多”按钮。
我不小心点击了“显示更多”按钮,因为我看不到任何应用的:focus
样式,无论是自定义的还是本机的。 我发现原生样式被outline-width
覆盖:
GitHub 键盘辅助功能
好的,上班时间。 哪里比在代码之家 github.com 工作更好?
我注意到关于 GitHub 的三件事:一件很棒,一件合理,一件糟糕。
首先,好的。
“跳至内容”链接
GitHub 提供了一个Skip to content
链接,它会跳过主菜单。
如果您在专注于“跳至内容”链接时按ENTER ,您将跳过页面顶部的所有菜单项,并可以开始在内容的主要区域内切换,从而节省导航时间。 这是一种常见的可访问性模式,对键盘和屏幕阅读器用户都非常有用。 如果您提供跳过链接,大约 30% 的屏幕阅读器用户会使用跳过链接。
或者,一些网站选择将主要内容放在阅读顺序的首位,位于导航上方。 这种方法已经过时了,因为它打破了让你的 DOM 内容与视觉顺序相匹配的准则(除非你的导航在视觉上显示在底部)。 虽然这种方法意味着我们根本不需要“跳过导航”链接,但我们可能需要一个“跳过导航”链接来代替它。
选项卡查看内容
我注意到与“非键盘”版本不同的一个功能是代码故障指示器。
使用鼠标,您可以单击任何存储库下方的彩色条,以查看存储库中使用的不同编程语言的按比例细分。 使用键盘,您实际上无法导航到彩色条,但是当您在元信息的末尾进行标签时,语言会自动出现。
这似乎没有必要——我很乐意在彩色条上按 Tab键并按 ENTER 键——但这种不同的行为也不会造成任何伤害。
隐形链接
我遇到的一件有问题的事情是,在右上角点击我的个人资料图片后,有一个“不可见”的链接。 我的标签顺序将标签到图片,然后到这个不可见的链接,然后到 repo 上的“观看”按钮(参见下面的 gif)。 我不知道隐形链接做了什么,所以当我意识到我在上面时,我按了ENTER并立即退出!
仔细观察,我似乎导航到了一个“仅限屏幕阅读器”表单( sr-only
是一个常见的屏幕阅读器类名称),它具有“退出”功能。
此退出链接是您个人资料下拉菜单中退出链接的补充:
我不确定是否需要两个单独的 HTML 退出链接,因为屏幕阅读器用户应该能够触发下拉菜单并导航到主退出链接。 如果我们想保留单独的链接,我建议对屏幕阅读器内容应用:focus
样式,这样有视力的用户就不会意外触发自己退出!
如何制作“跳转到内容”快捷方式
那么我们如何重新创建“跳到内容”快捷方式呢? 实现起来非常简单,但要想变得完美可能会很棘手——所以这就是我认为是跳过链接解决方案的圣杯。
“跳过链接”也称为“跳过导航”、“跳过主导航”、“跳过导航链接”或“跳到主要内容”。 “跳到主要内容”可能是最清楚的,因为它告诉您要导航到哪里,而不是您要跳过的内容。
理想情况下,快捷链接应该直接出现在开始<body>
标记之后。 它可以稍后出现在 DOM 中,即使在页脚之后,只要您有一个tabindex="1"
属性来强制它成为 tab 顺序中的第一个交互式元素。 但是,使用数字大于零的 tabindex 通常是不好的做法,并且在使用 Lighthouse 等验证工具时通常会导致警告。
依赖tabindex
并不是万无一失的,因为您可能有多个与tabindex="1"
的链接。 在这些情况下,首先获得选项卡焦点的是第一个链接,而不是任何后面的链接。 在此处阅读有关使用 tabindex 属性的更多信息,但请记住,为了安全起见,最好将链接物理移动到 DOM 的开头。
<a class="screen-reader-shortcut" href="#main-content"> Skip to main content </a>
“跳至主要内容”链接仅限于视力正常的用户使用,他们已经可以用眼睛跳过导航。 因此,虽然有些网站始终保持跳过链接可见,但现在的惯例是保持链接隐藏,直到您进入它,此时它处于焦点并获得:focus
伪选择器应用的样式。
.screen-reader-shortcut { position: absolute; top: -1000em; } .screen-reader-shortcut:focus { position: fixed; top: 0; left: 0; z-index: 999; /* ...and now any nice styling you want to apply... */ padding: 1em; background-color: rgb(114, 105, 105); color: white; text-decoration: none; }
那么,我们实际上要跳到什么地方呢? #main-content
是什么? 它可以是任何东西:
- 内联内容
即你的h1
标签的id:<h1 id="main-content">
。 - 容器
例如,围绕您的主要内容的容器的 ID,例如<main id="main-content">
。 - 兄弟锚
您可以链接到主要内容上方的命名标签,例如<a name="main-content"></a>
。 这种方法通常在较早的教程中有所描述——这些天我不推荐它。
为了最大限度地兼容所有屏幕阅读器,我建议链接到h1
标签。 这是为了确保在您使用跳过链接后立即读出内容。 链接到容器会导致有趣的行为,例如屏幕阅读器开始读出容器内的所有内容。
您的#main-content
还应该有一个-1
的tabindex
,以确保它可以通过编程获得焦点。 否则,某些屏幕阅读器可能不服从跳过链接。
<h1 tabindex="-1">This is the title of the page</h1>
最后一个考虑因素:旧版浏览器支持。 如果您有足够多的 IE9 或更低版本的用户,您可能需要对您的跳过链接应用一个小的 JavaScript 修复,以确保焦点确实按预期转移,并且您的用户成功跳过您的导航。
为什么我们要重新发明轮子?
作为网络开发人员,我们必须在我们所有的网站上实施这种“跳过导航”黑客,这似乎很疯狂。 你会认为我们可以让标准来完成工作。
从 HTML5 开始,我们就有了语义元素,例如<main>
、 <nav>
和<header>
。 在此之前,我们有 ARIA 地标,例如role="main"
、 role="navigation"
和role="banner"
。 在当前的网络环境中,最佳实践要求两者都需要,即<main role="main">
,这严重违反了 DRY 原则,但我们开始了。
有了这些丰富的语义,您希望浏览器能够开始原生支持通过这些标志性区域进行导航,例如,通过为用户提供键盘快捷键以直接进入网页的<main>
部分。 没有这样的运气——目前没有原生支持。 您最好的选择是通过 Chrome、Opera 或 Firefox 的键盘扩展使用 Landmark Navigation。
但是,屏幕阅读器用户可以开始直接导航到这些地标区域。 例如,在 Mac 上的 VoiceOver 上,您可以按CTRL + ALT + U来调出地标菜单并转到“主要”地标,这是访问主要内容的快速且一致的快捷方式。 当然,这依赖于网站正确标记其文档。
如果您希望网站可以通过地标区域导航,这是一个很好的起点:
<body> <header role="banner"> <!-- Logo and things can go here --> <nav role="navigation"> <!-- Site navigation links go here --> </nav> </header> <main role="main"> <!-- Main content lives here - including our h1 --> </main> <footer role="contentinfo"> <!-- Copyright statement, etc --> </footer> </body>
所有这些标记都是口渴的工作。 是时候喝杯咖啡了。
契约咖啡
我记得看到了 pactcoffee.com 的传单……我们去看看吧!
饼干横幅
“Cookie 政策”横幅是您在这里注意到的第一件事,忽略它几乎是有视力的鼠标用户的本能反应。 一些屏幕阅读器用户可能不关心它(如果你是盲人,在你到达它之前你不会知道它在那里),但作为一个有视力的用户,你看到它,你想杀死它,并且在这个网站,你需要在关闭它之前点击所有其他链接。
我使用 ChromeLens 辅助功能扩展来跟踪页面的标签顺序:
这可以通过将通知移动到文档顶部来解决(它仍然可以使用 CSS 在视觉上锚定到底部),或者通过向 OK 按钮添加tabindex="1"
来解决。 我建议将此修复应用于任何期望用户想要关闭它的内容。
更多隐形链接
就像在 GitHub 上一样,我发现自己使用了一个不明确目的的屏幕外元素。 事实证明,它是位于“查看更多……”卡片后面的“少看……”切换开关。
这是因为“隐藏”区域并没有真正隐藏,它只是旋转了 180 度,使用:
transform: rotateY(180deg);
…这意味着“少看…”按钮仍然是标签顺序的一部分。 这可以通过应用display: none
来解决,直到应用程序准备好触发旋转:
点了咖啡。 现在是时候继续我的研究了。
IT世界
我正在为这篇文章做一些研究,并遇到了一个与我自己类似的实验; 凯文·珀迪(Kevin Purdy)只使用键盘浏览了 7 天的网页。 我觉得很讽刺的是,在同样的限制下我无法阅读他的文章!
问题是一个整页的 cookie 横幅,要求我“更新隐私设置”或接受默认的 cookie 设置。 无论我点击多少次,我都无法专注于 cookie 横幅并将其关闭。
我深入研究了源代码以了解发生了什么。 有那么一瞬间,我想它可能是我们的死对头, outline
CSS 属性。
检查“更新隐私设置”链接,我可以看到一个outline: 0
我怀疑。 所以也许我专注于按钮,但发生这种情况时没有视觉反馈?
我尝试将状态设置为:hover
以查看我是否错过了作为键盘用户的任何样式:
果然,链接在悬停时变成了漂亮、明显的橙色——这是我从未在焦点上看到的:
万岁! 破解它! 我从未见过:focus
状态,因为自定义样式仅应用于:hover
。 我一定是在没有注意到的情况下跳过了按钮,对吧?
错误的。 即使我在本地破解 CSS,我也看不到任何焦点样式,这意味着我什至没有进入 cookie 模式。 然后我意识到……链接缺少href
属性:
那才是真正的罪魁祸首。 outline: 0
不是问题——浏览器永远不会跳转到链接,因为它不是一个有效的链接!
从 HTML 5.2 规范:
链接的目的地由 href 属性给出,该属性必须存在并且必须包含可能被空格包围的有效非空 URL。 如果没有 href 属性,则该元素不定义链接。
给链接一个href属性——即使它只是#
——会使它们成为有效的链接,并将它们添加到页面的标签顺序中。
有趣的是,那天晚些时候,我在 PC World 上收到了一篇文章来阅读,我遇到了完全相同的问题。
似乎两个站点都使用相同的同意管理平台 (CMP)。 我进行了一些挖掘并推断它正在影响同一公司拥有的许多站点,并且此后直接与他们联系并提出了修复建议。
动能
我的厨房水龙头漏水了,我一直想把它换掉。 我在当地报纸上看到了 kinetico.co.uk 的广告,所以我想看看。
我无法导航到“厨房水龙头”部分,因为该链接隐藏在“盐和墨盒”父链接后面,该链接仅在悬停时显示其子链接。 有趣的是,该网站具有足够的前瞻性,可以提供“跳转到内容”链接(在上面的 gif 中简要显示),但无法创建可访问的菜单!
这是菜单出错的地方——它只在父菜单项悬停时显示子菜单:
修复它说起来容易做起来难。 在大多数情况下,您也可以将选择器“加倍”以应用于焦点:
li:hover .nav_sub_menu, li:focus .nav_sub_menu { }
但这在这种情况下不起作用,因为虽然<li>
元素是可悬停的,但它不可聚焦。 <li>
内的链接是可聚焦的。 但是子菜单不在链接内,它在它旁边,所以我们需要应用兄弟选择器来在链接获得焦点时显示子菜单。
li:hover .nav_sub_menu, a:focus + .nav_sub_menu { }
这个调整意味着当我们在键盘上切换到父菜单项时,我们可以看到我们的子菜单。 但是当您尝试进入子菜单时会发生什么?
当我们从父菜单项 Tab 时,焦点会按预期转移到子菜单中的第一个链接。 但这会将焦点从父菜单链接上移开,这意味着子菜单被隐藏并且子菜单项再次从选项卡顺序中删除!
这是一个可以使用:focus-within
解决的问题,如果父元素或其任何子元素具有焦点,则可以将样式应用于父元素。 所以,在这种情况下,我们必须增加三倍:
li:hover .nav_sub_menu, /* hover over parent menu item, show child menu */ a:focus + .nav_sub_menu, /* focus onto parent menu item, show child menu */ .nav_sub_menu:focus-within { /* focus onto child menu item, keep showing child menu */ }
我们的菜单现在可以通过纯 CSS 完全通过键盘访问。 我喜欢有创意的 CSS 解决方案,但这里有一点警告:当涉及到键盘导航时,很多“纯 CSS”的解决方案都会失败。 避免使用 JavaScript 并不一定会使网站更易于访问。
实际上,在这种情况下,JS 驱动的菜单可能会更好,因为浏览器对此解决方案的支持仍然很差。 :focus-within
目前只能在 Chrome、Firefox 和 Safari 中使用。 即使在 Chrome 中,我也发现它与display: none
用于显示/隐藏子菜单的逻辑; 我不得不通过设置opacity: 0
来隐藏我的菜单项。
好的,我今天结束了。 现在是时候放松一下社交媒体了。
Facebook 在这方面做得非常出色,提供了键盘可访问性方面的大师级课程。
第一次按TAB键时,会打开一个隐藏菜单,提供当前页面最热门部分的快捷方式以及其他热门页面的链接。
当您使用箭头键循环浏览页面部分时,这些部分会在视觉上突出显示,以便您可以看到您将要跳转到的位置。
最有用的功能是 Facebook 提供了一个OPT + / (或ALT + / )快捷方式来随时返回菜单,利用 aria-keyshortcuts 属性。
<div class="a11y-help"> Press opt + / to open this menu </div> <div aria-label="Navigation Assistant" aria-keyshortcuts="Alt+/" role="menubar"> <a class="screen-reader-shortcut" tabindex="1" href="#main-content"> Skip to main content </a> </div>
不像'skip to main content'链接,它建立在本地锚定技术之上并且“正常工作”, aria-keyshortcuts
属性要求作者实现所有键盘行为,所以你将不得不写一些如果您想使用它,请自定义 JavaScript。
这是一些隐藏和显示menubar
区域的 JS,这是一个有用的起点:
const a11yArea = document.querySelector('*[role="menubar"]'); document.addEventListener('keydown', (e) => { if (e.altKey && e.code === 'Slash') { a11yArea.style.display = a11yArea.style.display === 'block' ? 'none' : 'block'; } });
概括
这个实验混合了很棒的键盘体验和糟糕的键盘体验。 我有三个主要的外卖。
保持时尚
到目前为止,我今天遇到的最常见的键盘可访问性问题是可选项卡元素缺乏焦点样式。 在不定义任何自定义焦点样式的情况下抑制本机焦点样式,这使得确定您在页面上的位置变得非常困难,甚至是不可能的。 删除大纲是一种常见的失礼行为,甚至有专门的网站。
确保本地或自定义焦点样式可见是您在键盘可访问性领域可以做的最有影响力的事情,而且通常是最简单的事情之一; 在现有的:hover
样式上加倍选择器的简单案例。 如果你看完这篇文章后只做一件事,那就是在你的 CSS 中搜索outline: 0
和outline: none
。
语义是关键
您尝试在新选项卡中打开链接多少次,只是为了重定向当前窗口? 它时不时地发生在我身上,虽然很烦人,但我很幸运,这是我在使用网络时倾向于面临的唯一可用性问题之一。 此类问题源于滥用平台。
让我们看看这里的代码:
<span>Click here</span>
有能力、有视力的用户可以点击<span>
并被重定向到 Google。 但是,因为这是一个<span>
而不是链接或按钮,所以它不会自动具有任何焦点,因此键盘或屏幕阅读器将无法与之交互。
键盘用户是依赖标准的用户,而有能力的、有视力的人口统计有足够的特权来与元素进行交互,尽管它不符合标准。
使用平台的原生功能。 编写良好、干净的 HTML,并使用 https://validator.w3.org 等验证器来捕获锚点上缺少href
属性等问题。
内容是关键
您可能需要显示 cookie 通知、订阅表格、广告或广告屏蔽通知。
尽你所能使这些体验不引人注目。 如果你不能让他们不引人注目,至少让他们不被打扰。
用户在那里看到您的内容,而不是您的横幅,因此将这些可关闭的元素放在您的 DOM 中,以便可以快速关闭它们,或者如果您无法移动它们,则回退到使用tabindex="1"
。
最后,通过实施“跳到主要内容”链接的圣杯,支持您的用户尽快访问您的内容。
请继续关注本系列的下一篇文章,当我使用屏幕阅读器一天时,我将在其中建立一些这些技术。