優化網站accessibility之aria-live應用
2023-11-26 18:04:12
好的Accessibility網站能讓障礙者更舒服地瀏覽網頁,而障礙者分成很多種,例如聽覺障礙、視覺障礙、行動障礙等,接下來會針對視覺障礙的accessibility設定將aria-live導入網頁的通知訊息及輪播元件。
---
## 什麼是aria-live
以不重新刷新頁面的情況下去更新動態的內容,通常為一個小區域的內容,而此內容的區域需標註為aria-live,讓使用者能在不把焦點放上此區域的情況下聽到screen reader(螢幕報讀軟體ex:voiceover, NVDA)報讀此區域更新的內容。aria-live有三個設定值,分別為 `off`, `polite`, `assertive`。
這三個設定值分別對應到screen reader的報讀優先順序。`off` 為靜音,screen reader不會報讀此區域的更新內容; `polite`為中間順序,當screen reader正在報讀其他內容時,被設定為`polite`的區域則會被安排到下一個報讀的訊息;`assertive` 為最優先的順序,將會直接插播為第一則訊息讓sceern reader報讀。
## 通知訊息元件範例
由於通知訊息有即時性且只會顯示在網頁上幾秒鐘,所以將通知訊息的內容加上aria-live=”assertive”的設定,當有新訊息跳出,screen reader則會馬上報讀。
```jsx
<div
v-if="userPopupMessage.content.length > 0"
aria-live="assertive"
>
<p class="text-sm font-medium text-gray-700">
{{ userPopupMessage.content }}
</p>
</div>
```
## 輪播元件範例
此輪播元件為自動撥放,當設定值固定為`polite`,使用者瀏覽到其他區域時,會持續穿插輪播的內容,此結果並不符合使用情境,所以將`polite`及`off`交替使用,當使用者聚焦在輪播元件區域包含上下一張及底下控制點的按鈕時,將設定值從`off`變更為`polite`,使用者點擊輪播的控制按鈕使得輪播內容更新時,screen reader就會報讀更新內容,離開輪播元件區域後,screen reader則不報讀更新內容。
以下範例使用headlessUI的tab元件實作成輪播元件
```jsx
<template>
<TabGroup :selected-index="activeSlideIndex" @change="getActiveSlideIndex">
<div class="flex items-center justify-center">
<button aria-label="上一張圖片" @click="toPrev"
@focus="autoSlideOff"
@blur="autoSlideOn"
@mouseenter="autoSlideOff"
@mouseleave="autoSlideOn">
<ChevronLeftIcon
class="h-6 w-6 cursor-pointer text-indigo-600"
aria-controls="carousel"
/>
</button>
<!--To put aria-live at the element which you want screen reader read it out. -->
<TabPanels class="carousel-container relative" :aria-live="liveRegion">
<TabPanel v-for="item in banners" :key="item.id"
@focus="autoSlideOff"
@blur="autoSlideOn"
@mouseenter="autoSlideOff"
@mouseleave="autoSlideOn"
>
<a :key="item.id" tabindex="-1" :href="item.url" target="blank">
<img v-show="activeSlideIndex == banners.indexOf(item)"
class="absolute h-full w-full rounded-md"
:src="item.imageUrl"
:alt="item.title"
/>
</a>
</TabPanel>
</TabPanels>
<button aria-label="下一張圖片" @click="toNext"
@focus="autoSlideOff"
@blur="autoSlideOn"
@mouseenter="autoSlideOff"
@mouseleave="autoSlideOn">
<ChevronRightIcon
class="h-6 w-6 cursor-pointer text-indigo-600"
aria-controls="carousel"
/>
</button>
</div>
<TabList class="mt-5 flex justify-center space-x-5">
<Tab v-for="(dot, index) in banners" :key="dot.id" v-slot="{ selected }" as="template">
<div :aria-label="`第${index + 1}張`" aria-controls="carousel"
@focus="autoSlideOff"
@blur="autoSlideOn"
@mouseenter="autoSlideOff"
@mouseleave="autoSlideOn"
></div>
</Tab>
</TabList>
</TabGroup>
</template>
<script setup>
import { ChevronRightIcon, ChevronLeftIcon } from "@heroicons/vue/solid";
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from "@headlessui/vue";
import { computed, ref, defineProps, onMounted } from "vue";
const liveRegion = ref("off");
let autoSlide;
const autoSlideOn = () => {
autoSlide = setInterval(slide, 5000);
liveRegion.value = "off";
};
const autoSlideOff = () => {
clearInterval(autoSlide);
liveRegion.value = "polite";
};
</script>
```
### Resource
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions
https://www.w3.org/WAI/ARIA/apg/patterns/carousel/examples/carousel-1-prev-next/
點擊複製文章連結
X