無障礙、HTML 小細節、焦點、a11y、Accessibility、框架選擇
無障礙開發仍是應該從 HTML
開始聊起,不管是盲人閱讀器仍是瀏覽器等工具最核心的部分仍是在 HTML
,畢竟沒了 CSS
只是不美觀了,沒了 JavaScript
只是少了交互和無限擴展的可能性。javascript
有的同窗會說了產品和老闆拿着鞭子在後頭趕馬車哪裏有時間寫這些
。現實是這樣的,可是在選擇UI框架的時候能夠選擇 無障礙
作得好的來提高網站的友好度,有句話說得好 居廟堂之高則憂其民,處江湖之遠則憂其君
,靈活變通下不影響生活體驗豈不是美哉?css
HTML
標籤元素中還有一種比較少人知道的分類方法:交互標籤
和 非交互標籤
,在無障礙開發中須要留意的即是這兩者。交互標籤
每每會和 焦點
一塊兒出現,按下 tab
鍵選擇頁面上的 交互標籤
這個時候交互標籤會被 藍色的 焦點
框覆蓋,若是想反向選擇可使用 shift + tab
。html
在掘金我的主頁裏按下 tab
鍵後,藍色的焦點
框會從 logo 到 首頁一個個連接遍歷下來,在這個過程當中能夠發現 連接
、按鈕
、搜索框
都會產生焦點。細心的同窗若是打開控制檯會還會發現,跳轉的順序和標籤在 HTML 中出現的前後順序
有關。java
運動覺障礙的用戶,例如霍金大大就能夠利用他的三個指頭配合 tab
和 shift + tab
來瀏覽 掘金
並在掘金上作交互性的操做。除此以外鍵盤上的 方向鍵
也是移動和瀏覽頁面必不可少的一部分,你可使用 上下鍵
來是的頁面能夠上下滾動,也能夠在 select 標籤
中選擇選項。git
更多無障礙羣體內容能夠閱讀 無障礙世界
正所謂 工欲善其事必先利其器
對於被 焦點
選中的元素,能夠經過 document.activeElement
來獲取。固然也可使用插件來完成,這裏推薦谷歌瀏覽器的一款插件 accessibility developer tools
。github
經過這個測試能夠知道關於交互標籤的情報
即是 連接
、按鈕
、搜索框
是交互標籤,下面用選擇器來總結一下 交互標籤
:瀏覽器
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);
除了 交互標籤
中提到的標籤外都屬於 非交互標籤
,有些開發老司機可能會問:微信
非交互標籤
變成 交互標籤
怎麼辦?這裏便須要一個很常常被忽略掉的標籤 tabindex
:框架
<element tabindex="number">
它根據 tabindex
從小到大來控制 tab
的跳動順序,雖然能夠控制整個頁面的瀏覽順序,可是最好只使用 0
來指定 tabindex
屬性。在上面也提到過打開控制面板查看頁面結構
會發現 tab
默認的跳轉順序
和 標籤順序
是一致的,若是破壞掉了這個順序對於一些不兼容 tabindex
的盲人輔助工具、瀏覽器會形成沒法兼容的狀況。dom
從下面例子也能瞭解到 頁面結構順序
很是重要,若是屏幕閱讀器
不支持 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:block
和 visibility:visible
進行顯示。
掘金的隱藏菜單作得挺好的,不會讓焦點跳轉到隱藏菜單
,美中不足的是隻能經過鼠標懸浮來顯示菜單
,不能經過tab
和enter
進行選中操做。
經過點擊菜單欄來進行頁面的切換,可是你有思考過當切換完菜單,用戶要瀏覽內容還得按多少下 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=-1
和 focus()
來快速的將焦點
切換至頁面內容 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
的內容也在 dom 元素裏,使用 tab
進行切換時會致使切換的焦點
沒法落在 Alert
對話框中,這裏推薦閱讀 SweetAlert
的源碼它的無障礙作得很是棒,重點閱讀 getFocusableElements 和 restoreActiveElement 這兩個函數。
主要的流程分爲:
document.activeElement
記錄當前的焦點元素
和頁面 x
和 y
座標。Alert
對話框中的 變成交互標籤
上文中提到的 tags
。tag
的屬性爲 focus()
。tag
被點擊時須要循環重置到第一個 tag
。Alert
則經過一開始記錄的焦點元素
和頁面 x
和 y
座標進行恢復。在 Element UI 中的自定義元素都作得不錯,就是對於視障用戶 焦點focus
的顏色區分度不夠,就連小二本身都看不清已選擇的元素時被focus
在哪裏,不過能夠經過修改 is-focus
來修改樣式顏色:
tab
和 space
都有實現。tab
和 space
都有實現。tab
和 enter
都有實現。tab
和 enter
、方向鍵
都有實現。Material UI
在無障礙上就作得很是好,而在 Ant Design
無障礙相關的 交互元素
就作得不怎麼好了,若是產品目標羣體中有須要 無障礙
相關的服務,在選擇框架時能夠試試其中的 交互元素
作得如何,畢竟站在巨人的肩膀上比本身造輪子快又好
。
在困惑的城市裏總少不了並肩同行的
夥伴
讓咱們一塊兒成長。
點贊
。小星星
。m353839115
。
本文原稿來自 PushMeTop