每日 30 秒 ⏱ 扼住焦点的喉咙

简介

无障碍、HTML 小细节、焦点、a11y、Accessibility、框架选择javascript

无障碍开发仍是应该从 HTML 开始聊起,不管是盲人阅读器仍是浏览器等工具最核心的部分仍是在 HTML,毕竟没了 CSS 只是不美观了,没了 JavaScript 只是少了交互和无限扩展的可能性。css

有的同窗会说了产品和老板拿着鞭子在后头赶马车哪里有时间写这些。现实是这样的,可是在选择UI框架的时候能够选择 无障碍 作得好的来提高网站的友好度,有句话说得好 居庙堂之高则忧其民,处江湖之远则忧其君,灵活变通下不影响生活体验岂不是美哉?html

键盘与交互

HTML 标签元素中还有一种比较少人知道的分类方法:交互标签非交互标签,在无障碍开发中须要留意的即是这两者。交互标签 每每会和 焦点 一块儿出现,按下 tab 键选择页面上的 交互标签 这个时候交互标签会被 蓝色的 焦点 框覆盖,若是想反向选择可使用 shift + tabjava

在掘金我的主页里按下 tab 键后,蓝色的焦点框会从 logo 到 首页一个个连接遍历下来,在这个过程当中能够发现 连接按钮搜索框 都会产生焦点。细心的同窗若是打开控制台会还会发现,跳转的顺序和标签在 HTML 中出现的前后顺序有关。git

掘金焦点

运动觉障碍的用户,例如霍金大大就能够利用他的三个指头配合 tabshift + tab 来浏览 掘金 并在掘金上作交互性的操做。除此以外键盘上的 方向键 也是移动和浏览页面必不可少的一部分,你可使用 上下键 来是的页面能够上下滚动,也能够在 select 标签 中选择选项。github

更多无障碍群体内容能够阅读 无障碍世界浏览器

调试工具

正所谓 工欲善其事必先利其器 对于被 焦点 选中的元素,能够经过 document.activeElement 来获取。固然也可使用插件来完成,这里推荐谷歌浏览器的一款插件 accessibility developer toolsbash

交互标签

经过这个测试能够知道关于交互标签的情报即是 连接按钮搜索框 是交互标签,下面用选择器来总结一下 交互标签微信

const tags = [
    'a[href]', 'area[href]', 'audio[controls]', 'video[controls]',
    'input:not([disabled])', 'select:not([disabled])',
    'textarea:not([disabled])', 'button:not([disabled])',
    'iframe', 'object', 'embed', '[contenteditable]',
    '[tabindex="0"]',
];

const allTagsDOM = document.querySelectorAll(tags.join(','));

console.log(allTagsDOM);
复制代码

非交互标签

除了 交互标签 中提到的标签外都属于 非交互标签,有些开发老司机可能会问:框架

  • 若是想让 非交互标签 变成 交互标签 怎么办?
  • 使用自定义标签例如 select 或者 button 怎么办?

变成交互标签

这里便须要一个很常常被忽略掉的标签 tabindex

<element tabindex="number">
复制代码

它根据 tabindex 从小到大来控制 tab 的跳动顺序,虽然能够控制整个页面的浏览顺序,可是最好只使用 0 来指定 tabindex 属性。在上面也提到过打开控制面板查看页面结构 会发现 tab 默认的跳转顺序标签顺序是一致的,若是破坏掉了这个顺序对于一些不兼容 tabindex 的盲人辅助工具、浏览器会形成没法兼容的状况。

破坏标签顺序

从下面例子也能了解到 页面结构顺序 很是重要,若是屏幕阅读器不支持 tabindex 时便会先读取footer标签的中内容,对于盲人来讲可能会一头雾水不知道网站怎么使用:

代码
<!-- 正常顺序 -->
<!--<header>header</header>-->
<!--<main>main</main>-->
<!--<footer>footer</footer>-->

<!-- tabindex 控制顺序 -->
<footer tabindex='3'>footer</footer>
<main tabindex='2'>main</main>
<header tabindex='1'>header</header>
复制代码
效果

破坏标签顺序

破坏显示顺序

除此以外当使用 css 样式 float: right 改变页面渲染的排列顺序也可能会形成影响,对于习惯从右向左阅读的用户来讲会形成困惑找不到焦点的位置。

代码
<style>
    button { float: right; }
</style>

<button>1</button>
<button>2</button>
<button>3</button>
复制代码
效果

破坏显示顺序

自定义元素

当自定义元素时须要把元素默认的 焦点 功能模拟出来进行替换便可。在上文提到了 非互动标签 转换 互动标签 利用 tabindex 这个属性来完成,其实还有一个小技巧利用 tabindex=-1 设置标签后,对应的 DOM 节点将会拥有 focus() 方法,利用这一点能够配合 JavaScript 能够实现很是多的功能。

主要须要注意的是 tab键enter键方向键space键 的功能。

看不见的元素

提到看不见的元素不少同窗可能会一头雾水,最多见的看不见标签即是隐藏的导航菜单栏

导航菜单栏

上面讲到的 交互标签 会按顺序被 tab 选中成为焦点,导航菜单中的元素是一个个的 a[href],当在使用 tab 浏览的时候焦点会被锁定在这个隐藏的菜单之中。若是没有把鼠标悬浮在首页上时,用户可能会产生困惑 焦点去哪里了

这个时候的解决方法即是使用 display:none 或者 visibility:hidden 来控制标签不在 tab 的选着范围中。二者区别是 display:none 会让元素在渲染树中消失,不占用任何空间,visibility:hidden 则保留元素占据的空间,也依旧在渲染树中。当须要的时候使用 display:blockvisibility:visible 进行显示。

掘金的隐藏菜单作得挺好的,不会让焦点跳转到 隐藏菜单,美中不足的是只能经过鼠标悬浮来 显示菜单 ,不能经过 tabenter 进行选中操做。

实例

主内容快速切换

经过点击菜单栏来进行页面的切换,可是你有思考过当切换完菜单,用户要浏览内容还得按多少下 tab 才能进入内容标签嘛?若是菜单栏有五六十个的状况是多么可怕,你还真别说没有 某东某宝 的菜单项就有这么多:

某东

不过当选中标签按下 enter 时,他们会直接打开新的页面算是减小了用户须要 tab 的次数,不过在新页面上仍是要从新点击屡次 tab 才能浏览内容。咱们能够利用 锚点tabindex=-1 来帮助用户快速切换内容焦点:

<a class="super-skip" href="#content">快速进入内容</a>

<nav>
    <a class="menu-items" data-page="home" href="/home">Home</a>
    <a class="menu-items" data-page="post" href="/post">Post</a>
    <a class="menu-items" data-page="user" href="/user">User</a>
</nav>

<main id="content" tabindex="-1">
    主要内容
</main>
复制代码

这下用户按下 tab 即可以快速选择是否直接浏览内容,可是这个 a 标签 会影响到页面的美观,能够利用 css 样式中的 position: absolute:focus 来帮助隐藏 a 标签 功能保持不变codepan

.super-skip {
    position: absolute;
    top -40px;
    left: 0; 
    z-index:100;
}

.super-skip:focus {
    top: 0;
}
复制代码

快速切换菜单

在单页面浏览中用户会在 菜单 中选择 菜单项,可是页面内容改变的却仍是要 tab 浏览完剩下的标签才能将 焦点 切换到 页面内容,能够利用 tabindex=-1focus() 来快速的将焦点切换至页面内容 codepan

<style> .page { display: none; } .active { display: block; } </style>

<nav>
    <a class="menu-items" data-page="home" href="/home">Home</a>
    <a class="menu-items" data-page="post" href="/post">Post</a>
    <a class="menu-items" data-page="user" href="/user">User</a>
</nav>

<div class="home page active">
    <h1 class="title" tabindex="-1">home</h1>
</div>

<div class="post page">
    <h1 class="title" tabindex="-1">post</h1>
</div>

<div class="user page">
    <h1 class="title" tabindex="-1">user</h1>
</div>

<script> const doms = document.querySelectorAll('.menu-items'); const items = Array.from(doms); function superSkip(e) { const page = e.target.getAttribute('data-page'); const oldPage = document.querySelector('.active'); const newPage = document.querySelector(`.${page}`); const newPageTitle = document.querySelector(`.${page} .title`); // 切换页面 oldPage.classList.remove('active'); newPage.classList.add('active'); // 设置焦点 newPageTitle.focus(); e.preventDefault(); } items.forEach(i => i.onclick = superSkip); </script>
复制代码

Alert

在使用弹出自定义 Alert 时,因为 Alert 的内容也在 dom 元素里,使用 tab 进行切换时会致使切换的焦点 没法落在 Alert 对话框中,这里推荐阅读 SweetAlert 的源码它的无障碍作得很是棒,重点阅读 getFocusableElementsrestoreActiveElement 这两个函数。

主要的流程分为:

  • 利用 document.activeElement 记录当前的焦点元素和页面 xy 坐标。
  • 选着当前 Alert 对话框中的 变成交互标签 上文中提到的 tags
  • 设置第一个 tag 的属性为 focus()
  • 设置最后一个 tag 被点击时须要循环重置到第一个 tag
  • 若是关闭 Alert 则经过一开始记录的焦点元素和页面 xy 坐标进行恢复。

挑选框架

在 Element UI 中的自定义元素都作得不错,就是对于视障用户 焦点focus 的颜色区分度不够,就连小二本身都看不清已选择的元素时被focus在哪里,不过能够经过修改 is-focus 来修改样式颜色:

  • Radio 无障碍中 tabspace 都有实现。
  • Checkbox 无障碍中 tabspace 都有实现。
  • Select 无障碍中 tabenter 都有实现。
  • TimePicker无障碍中 tabenter方向键 都有实现。

Material UI 在无障碍上就作得很是好,而在 Ant Design 无障碍相关的 交互元素 就作得不怎么好了,若是产品目标群体中有须要 无障碍 相关的服务,在选择框架时能够试试其中的 交互元素 作得如何,毕竟站在巨人的肩膀上比本身造轮子快又好

无障碍相关内容

一块儿成长

在困惑的城市里总少不了并肩同行的 伙伴 让咱们一块儿成长。

  • 若是您想让更多人看到文章能够点个 点赞
  • 若是您想激励小二能够到 Github 给个 小星星
  • 若是您想与小二更多交流添加微信 m353839115

微信公众号

本文原稿来自 PushMeTop

相关文章
相关标签/搜索