每日 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

相關文章
相關標籤/搜索