成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

被多數(shù)前端開發(fā)忽略的重要特性!

開發(fā) 前端
可訪問性不是功能,而是責(zé)任。通過實現(xiàn)這些技術(shù)細節(jié),我們不僅滿足 WCAG 標(biāo)準(zhǔn),更是為所有用戶構(gòu)建真正的包容性網(wǎng)絡(luò)。從下一個功能需求開始,將可訪問性刻進你的開發(fā) DNA。

作為前端開發(fā)者,我們常常沉浸在UI動效、性能優(yōu)化和新技術(shù)棧的研究中,卻忽視了一個直接影響25%用戶的重要問題——Web 可訪問性。本文將深入解析前端可訪問性的核心要點及具體實現(xiàn)。

圖片

可訪問性是什么?

Web 可訪問性是指通過設(shè)計和開發(fā)技術(shù),確保網(wǎng)頁或應(yīng)用能夠被所有人無障礙地訪問和使用,包括殘障人士、老年用戶、臨時受傷者(如手部受傷)或使用特殊設(shè)備(如屏幕閱讀器、語音控制工具)的人群。其核心目標(biāo)是消除訪問障礙,實現(xiàn)信息平等。

Web 可訪問性的重要性:

  • 法律合規(guī):許多國家和地區(qū)(如歐盟、美國)要求公共網(wǎng)站必須符合可訪問性標(biāo)準(zhǔn)(如 WCAG),否則可能面臨法律風(fēng)險。如果你的應(yīng)用用戶人群是這些國家的,就需要特別關(guān)注開發(fā)中的可訪問性。
  • 用戶體驗:提升所有用戶的操作便利性,例如清晰的導(dǎo)航、高對比度配色對普通用戶同樣友好。
  • SEO 優(yōu)化:可訪問性實踐(如語義化 HTML)通常與搜索引擎優(yōu)化(SEO)兼容,提升搜索排名。

WCAG

WCAG(Web Content Accessibility Guidelines,網(wǎng)頁內(nèi)容可訪問性指南)是由 W3C(萬維網(wǎng)聯(lián)盟)制定的國際標(biāo)準(zhǔn),旨在確保網(wǎng)頁內(nèi)容對所有人均可訪問和使用。

根據(jù) Web 內(nèi)容可訪問性指南(WCAG),Web 可訪問性可以歸納為以下四個核心原則

  • 可感知: 用戶必須能夠感知提供的信息。

文本替代:為非文本內(nèi)容(如圖片、圖表)提供 alt 文本或描述。

多媒體可訪問:為視頻提供字幕,為音頻提供文本轉(zhuǎn)錄。

適配性:內(nèi)容在不同設(shè)備(如屏幕閱讀器、移動端)上可正常顯示。

  • 可操作: 用戶界面組件和導(dǎo)航必須是可操作的。
  • 鍵盤導(dǎo)航:所有功能可通過鍵盤(Tab、Enter、方向鍵)操作。
  • 避免閃爍內(nèi)容:防止快速閃爍的動畫引發(fā)光敏性癲癇。
  • 足夠時間:用戶有充足時間閱讀或操作(如表單填寫倒計時可延長)。
  • 可理解: 用戶必須能夠理解和使用信息和用戶界面。
  • 一致性:導(dǎo)航、標(biāo)簽、按鈕功能保持一致。
  • 錯誤提示:表單輸入錯誤時提供明確的文字說明和修正建議。
  • 語言明確:避免使用復(fù)雜術(shù)語,頁面語言通過 lang 屬性聲明。
  • 健壯: 內(nèi)容必須兼容當(dāng)前和未來的技術(shù)。
  • 語義化 HTML:使用標(biāo)準(zhǔn)標(biāo)簽(如 <button><nav>),避免濫用 <div> 模擬控件。
  • ARIA 支持:為動態(tài)內(nèi)容補充 ARIA 屬性(如 rolearia-label)。

WCAG 要求分為三個等級,從低到高依次為:

圖片

可訪問性的前端實現(xiàn)

Web 可訪問性需要貫穿開發(fā)全流程,從前端技術(shù)實現(xiàn)到設(shè)計協(xié)作,再到測試驗證。

語義化HTML

根據(jù)內(nèi)容的含義選擇合適的 HTML 標(biāo)簽,這有助于屏幕閱讀器等輔助技術(shù)理解頁面結(jié)構(gòu),方便用戶導(dǎo)航。

<!-- 錯誤:用 div 模擬按鈕 -->
<div onclick="submit()">提交</div>

<!-- 正確:語義化按鈕 -->
<button onclick="submit()">提交</button>

常見的語義化標(biāo)簽包括:

標(biāo)簽

作用

<header>

定義文檔或節(jié)的頁眉,包含介紹性內(nèi)容,如網(wǎng)站標(biāo)志、標(biāo)題、導(dǎo)航欄等

<nav>

專門定義導(dǎo)航鏈接部分,包含指向不同頁面或同一頁面不同部分的主要導(dǎo)航鏈接

<main>

規(guī)定文檔的主要內(nèi)容,該內(nèi)容應(yīng)獨一無二,不包含重復(fù)出現(xiàn)的內(nèi)容

<article>

表示文檔中獨立、完整且可獨立分發(fā)的內(nèi)容塊,如博客文章、新聞報道等

<section>

對文檔內(nèi)容進行分塊,將相似主題的內(nèi)容分組,不一定能獨立存在

<aside>

定義所處內(nèi)容之外的內(nèi)容,常表現(xiàn)為側(cè)邊欄或插入內(nèi)容,與周圍內(nèi)容相關(guān)但非主要部分

<footer>

定義文檔或節(jié)的頁腳,包含版權(quán)信息、作者信息、聯(lián)系方式等

<h1> - <h6>

定義不同級別的標(biāo)題,構(gòu)建文檔大綱結(jié)構(gòu),利于搜索引擎理解及用戶瀏覽

<ul>

創(chuàng)建無序列表,列表項無特定順序,以項目符號顯示

<ol>

創(chuàng)建有序列表,列表項按數(shù)字或字母順序排列,適用于強調(diào)順序的內(nèi)容

<dl>

創(chuàng)建定義列表,包含<dt>(定義術(shù)語)和<dd>(定義描述)對,展示術(shù)語及其定義

<blockquote>

定義從其他來源引用的內(nèi)容,視覺上常呈現(xiàn)為縮進,可搭配<cite>指定引用來源

<q>

定義短的行內(nèi)引用,瀏覽器自動在兩端加引號

<time>

定義日期和時間,方便瀏覽器和搜索引擎識別,可通過datetime屬性指定具體值

語義化 HTML 的好處:

  • 提高可訪問性: 語義化HTML可以幫助輔助技術(shù)(如屏幕閱讀器)更好地理解頁面結(jié)構(gòu)和內(nèi)容,從而為殘障用戶提供更好的體驗。
  • 增強SEO(搜索引擎優(yōu)化): 搜索引擎爬蟲依賴 HTML 標(biāo)簽來理解網(wǎng)頁的內(nèi)容和結(jié)構(gòu)。使用語義化HTML可以使搜索引擎更準(zhǔn)確地抓取和索引頁面,有助于提高搜索排名。
  • 改善代碼可讀性和維護性: 語義化HTML使代碼更具結(jié)構(gòu)性和邏輯性,易于理解和維護。
  • 符合Web標(biāo)準(zhǔn)和最佳實踐: 語義化HTML符合W3C和其他標(biāo)準(zhǔn)組織推薦的最佳實踐,有助于構(gòu)建高質(zhì)量的Web應(yīng)用。

鍵盤導(dǎo)航

鍵盤導(dǎo)航是 Web 可訪問性的重要組成部分,它允許用戶僅使用鍵盤來瀏覽和操作網(wǎng)頁,這對于那些無法使用鼠標(biāo)或其他指針設(shè)備的用戶(如肢體殘障人士、鍵盤快捷方式偏好者)來說至關(guān)重要。

可聚焦元素

可聚焦元素是指用戶可以通過鍵盤的 Tab 鍵將焦點移動到這些元素上的元素,并且焦點順序應(yīng)符合邏輯。常見的可聚焦元素包括鏈接(<a>)、按鈕(<button>)、輸入框(<input><textarea>)、下拉框(<select>)等。

<a href="#">前端充電寶</a>
<button>點擊我</button>
<input type="text" placeholder="輸入內(nèi)容">
<select>
    <option value="1">選項1</option>
    <option value="2">選項2</option>
</select>

在上述代碼中,用戶可以使用 Tab 鍵依次將焦點移動到鏈接、按鈕、輸入框和下拉框上。

焦點順序

  • 自然順序:鍵盤焦點的移動順序應(yīng)該與網(wǎng)頁內(nèi)容的邏輯和視覺順序一致。通常,焦點會按照 HTML 文檔中元素出現(xiàn)的先后順序進行移動。例如,在一個表單中,焦點會從第一個輸入框開始,依次移動到后續(xù)的輸入框、按鈕等元素。
  • 調(diào)整順序:在某些情況下,可能需要調(diào)整焦點順序。可以使用 tabindex 屬性來實現(xiàn)。

tabindex="0":將元素添加到正常的 Tab 順序中,即使該元素默認(rèn)不可聚焦。

tabindex="-1":使元素可聚焦,但不包含在正常的 Tab 順序中,可以通過 JavaScript 等方式將焦點設(shè)置到該元素上。

tabindex="正數(shù)":指定元素的焦點順序,數(shù)值越小越先獲得焦點,但不建議過多使用這種方式,因為可能會破壞自然的焦點順序。

焦點可見性

當(dāng)元素獲得焦點時,應(yīng)該有明顯的視覺指示,以便用戶清楚地知道當(dāng)前焦點所在的位置。可以通過修改元素的樣式(如改變邊框顏色、添加背景色、顯示下劃線等)來實現(xiàn)。

button:focus, input:focus, a:focus {
  outline: 2px solid #007BFF; /* 藍色邊框 */
  box-shadow: 0 0 5px rgba(0, 123, 255, 0.5); /* 添加陰影效果 */
}

注意事項:

  • 避免移除默認(rèn)的outline樣式,除非提供了更好的替代方案。
  • 提供高對比度的顏色,確保視覺上有足夠的可見性。

鍵盤操作支持

  • 常見操作:不同類型的元素應(yīng)該支持相應(yīng)的鍵盤操作。例如:
  • 鏈接:按下 Enter 鍵可以激活鏈接,跳轉(zhuǎn)到相應(yīng)的頁面。
  • 按鈕:按下 Enter 鍵或 Space 鍵可以觸發(fā)按鈕的點擊事件。
  • 輸入框:可以使用方向鍵在輸入框內(nèi)移動光標(biāo),按下 Enter 鍵在某些情況下可以提交表單。
  • 下拉框:使用方向鍵可以選擇下拉框中的選項,按下 Enter 鍵可以確認(rèn)選擇。
  • 自定義元素的鍵盤操作:對于自定義的交互元素(如自定義菜單、對話框等),需要通過 JavaScript 來實現(xiàn)相應(yīng)的鍵盤操作支持。例如,一個自定義菜單可以通過監(jiān)聽鍵盤事件,根據(jù)用戶按下的方向鍵來切換菜單項的選中狀態(tài),按下 Enter 鍵來執(zhí)行相應(yīng)的操作。

跳過導(dǎo)航

對于一些大型網(wǎng)頁,可能存在大量的導(dǎo)航鏈接和重復(fù)的內(nèi)容,用戶可能希望快速跳過這些內(nèi)容,直接訪問主要內(nèi)容。這時可以提供 “跳過導(dǎo)航” 鏈接。

實現(xiàn)方法:在頁面頂部添加一個隱藏的鏈接,當(dāng)用戶使用鍵盤將焦點移動到該鏈接時,鏈接顯示出來,用戶按下 Enter 鍵可以直接跳轉(zhuǎn)到頁面的主要內(nèi)容區(qū)域。

<a href="#main-content" class="skip-nav">跳過導(dǎo)航</a>
<header>
    <nav>
        <ul>
            <li><a href="#">首頁</a></li>
            <li><a href="#">產(chǎn)品</a></li>
            <li><a href="#">關(guān)于我們</a></li>
        </ul>
    </nav>
</header>
<main id="main-content">
    <h1>主要內(nèi)容標(biāo)題</h1>
    <p>主要內(nèi)容文本...</p>
</main>
.skip-nav {
  position: absolute;
  top: -40px;
  left: 0;
  background: #fff;
  padding: 8px;
  border: 1px solid #ccc;
  transition: top 0.3s ease;
}

.skip-nav:focus {
  top: 0;
}

這樣,當(dāng)用戶使用鍵盤將焦點移動到該鏈接時,鏈接會顯示出來,按下 Enter 鍵可以直接跳轉(zhuǎn)到頁面的主要內(nèi)容區(qū)域。

測試驗證

  • 手動測試: 使用鍵盤在網(wǎng)頁上進行導(dǎo)航,檢查焦點順序是否正確、焦點可見性是否明顯、元素的鍵盤操作是否正常等。

Tab鍵測試:通過Tab鍵逐個測試頁面上的交互元素,確保每個元素都可以被聚焦并操作。

Shift + Tab:測試反向?qū)Ш剑_保焦點順序正確。

Enter和Space 鍵:測試按鈕、鏈接等交互元素是否可以通過Enter或Space鍵激活。

Esc鍵:測試模態(tài)對話框、下拉菜單等是否可以通過Esc鍵關(guān)閉。

  • 自動化測試:使用 axe-core 工具庫進行檢查。

ARIA 屬性

ARIA(Accessible Rich Internet Applications)屬性是 HTML5 規(guī)范的一部分,旨在幫助開發(fā)者增強網(wǎng)頁的可訪問性,特別是在處理動態(tài)內(nèi)容和復(fù)雜用戶界面時。通過使用ARIA屬性,可以為屏幕閱讀器和其他輔助技術(shù)提供更多的信息,從而提升用戶體驗。

ARIA 屬性主要分為三類:角色、狀態(tài)、屬性。

角色

角色定義了元素在頁面中的功能或用途,常見的角色包括buttonmenudialog等。

  • role="button":將一個普通的 <div> 元素定義為按鈕,使其具有按鈕的語義。
<div role="button" tabindex="0">前端充電寶</div>
  • role="menu"role="menuitem":用于創(chuàng)建自定義菜單,明確菜單和菜單項的角色。
<ul role="menu">
    <li role="menuitem"><a href="#">選項1</a></li>
    <li role="menuitem"><a href="#">選項2</a></li>
</ul>
  • role="dialog":用于定義一個對話框。
<div id="dialog" role="dialog" aria-modal="true">
  <h2>標(biāo)題</h2>
  <p>內(nèi)容</p>
  <button id="closeDialog">關(guān)閉</button>
</div>

注意事項:

  • 盡量使用原生HTML元素(如<button><nav>等),它們自帶語義化角色。
  • 只有在必要時才使用role屬性來增強自定義組件的可訪問性。

狀態(tài)

狀態(tài)表示元素當(dāng)前的狀態(tài),如是否選中、是否展開等。常見的狀態(tài)包括aria-checkedaria-expanded等。

  • aria-checked:用于復(fù)選框和單選框,指示其選中狀態(tài)。
<input type="checkbox" id="check-box" aria-checked="false">
<label for="check-box">選擇</label>
  • aria - expanded:用于可展開 / 折疊的元素,如菜單、手風(fēng)琴組件等,指示其展開狀態(tài)。
<button aria - controls="content" aria - expanded="false">展開內(nèi)容</button>
<div id="content" hidden>具體內(nèi)容</div>

屬性

屬性提供了額外的信息,如標(biāo)簽、描述等。常見的屬性包括aria-labelaria-labelledbyaria-describedby等。

  • aria-label:為元素提供一個明確的標(biāo)簽,用于替代元素內(nèi)部的文本,特別是當(dāng)元素沒有可見文本時,適用于簡單的替代文本。
<input type="search" aria-label="搜索框">
<button aria-label="關(guān)閉菜單">X</button>
  • aria-labelledby:引用其他元素的ID作為標(biāo)簽來源,適用于引用現(xiàn)有文本作為標(biāo)簽的情況。
<h1 id="page-title">網(wǎng)站</h1>
<nav aria-labelledby="page-title">
  <ul>
    <li><a href="#home">首頁</a></li>
    <li><a href="#about">關(guān)于我們</a></li>
  </ul>
</nav>
  • aria-describedby用于為元素提供額外的描述信息,通常與表單驗證錯誤消息一起使用。
<label for="email">郵箱地址:</label>
<input type="email" id="email" name="email" aria-invalid="true" aria-describedby="email-error">
<span id="email-error" class="error">請輸入有效的郵箱地址</span>

多媒體內(nèi)容

確保多媒體內(nèi)容對所有用戶都是可訪問的,包括視力障礙者、聽力障礙者以及其他有特殊需求的用戶,是創(chuàng)建包容性網(wǎng)站的重要部分。

圖片可訪問性

  • 替代文本: 為圖像提供替代文本(alt屬性),以便屏幕閱讀器能夠描述圖像的內(nèi)容。需要注意:

提供有意義的alt屬性,避免使用空字符串(除非圖像是純粹裝飾性的)。

對于裝飾性圖像,可以使用alt=""來告訴屏幕閱讀器忽略該圖像。

<img src="logo.png" alt="公司Logo">
  • 長描述: 對于復(fù)雜的圖像或圖表,簡單的alt屬性可能不足以描述其全部內(nèi)容,此時可以使用 <figcaption> 標(biāo)簽結(jié)合 <figure> 標(biāo)簽為圖像添加說明。
<figure>
    <img src="complex_graph.png" alt="一張復(fù)雜的銷售數(shù)據(jù)折線圖">
    <figcaption>該折線圖展示了過去一年中不同季度的產(chǎn)品銷售數(shù)據(jù)變化趨勢。</figcaption>
</figure>

視頻可訪問性

  • 字幕: 為視頻添加字幕,幫助聽力障礙者理解視頻內(nèi)容,也有助于在嘈雜環(huán)境或用戶選擇靜音時理解視頻內(nèi)容。可以在 <video> 標(biāo)簽中使用 <track> 標(biāo)簽添加字幕文件,kind 屬性設(shè)置為 captions
<video controls>
  <source src="example.mp4" type="video/mp4">
  <track kind="captions" src="captions.vtt" srclang="zh" label="中文字幕">
</video>
  • 音頻描述: 音頻描述是對視頻中視覺內(nèi)容的口頭描述,幫助視力障礙者理解視頻中的重要視覺元素。同樣使用 <track> 標(biāo)簽來實現(xiàn),kind 屬性設(shè)置為 descriptions
<video controls>
    <source src="video.mp4" type="video/mp4">
    <track kind="descriptions" src="descriptions.vtt" srclang="zh" label="視頻描述">
</video>
  • 控制和交互: 提供易于使用的視頻控制功能,讓所有用戶都能方便地播放、暫停、調(diào)整音量、快進等。可以在 <video> 標(biāo)簽中添加 controls 屬性,顯示默認(rèn)的視頻控制條。也可以通過 JavaScript 自定義控制界面,但要確保其可通過鍵盤操作。
<video id="myVideo" controls>
  <source src="example.mp4" type="video/mp4">
</video>

<script>
  const video = document.getElementById('myVideo');

  // 添加鍵盤事件監(jiān)聽器
  document.addEventListener('keydown', (e) => {
    if (e.key = ' ') { // 空格鍵播放/暫停
      e.preventDefault();
      if (video.paused) {
        video.play();
      } else {
        video.pause();
      }
    } else if (e.key = 'ArrowLeft') { // 左箭頭后退5秒
      video.currentTime -= 5;
    } else if (e.key === 'ArrowRight') { // 右箭頭前進5秒
      video.currentTime += 5;
    }
  });
</script>

音頻可訪問性

  • 音頻轉(zhuǎn)錄: 為聽障用戶或在無法播放音頻的情況下提供音頻內(nèi)容的文字版本。
<audio controls>
    <source src="audio.mp3" type="audio/mpeg">
</audio>
<p>點擊 <a href="audio_transcription.txt">這里</a> 查看音頻轉(zhuǎn)錄文本。</p>
  • 音頻控制: 確保音頻播放器的控制按鈕可以通過鍵盤操作,并且對屏幕閱讀器友好。
<audio id="myAudio" controls>
  <source src="example.mp3" type="audio/mpeg">
</audio>

<script>
  const audio = document.getElementById('myAudio');

  // 添加鍵盤事件監(jiān)聽器
  document.addEventListener('keydown', (e) => {
    if (e.key = ' ') { // 空格鍵播放/暫停
      e.preventDefault();
      if (audio.paused) {
        audio.play();
      } else {
        audio.pause();
      }
    } else if (e.key = 'ArrowLeft') { // 左箭頭后退5秒
      audio.currentTime -= 5;
    } else if (e.key === 'ArrowRight') { // 右箭頭前進5秒
      audio.currentTime += 5;
    }
  });
</script>

整體策略

  • 自動播放限制: 避免自動播放多媒體內(nèi)容,特別是帶有聲音的視頻或音頻,以免干擾用戶的體驗。可以使用preload="none"preload="metadata"來延遲加載視頻,直到用戶明確請求播放。
<video controls preload="none">
  <source src="example.mp4" type="video/mp4">
</video>
  • 焦點管理: 確保當(dāng)多媒體內(nèi)容加載或動態(tài)更新時,焦點正確管理,不會導(dǎo)致用戶失去當(dāng)前的操作上下文。

表單設(shè)計

設(shè)計一個易于理解和使用的表單是提升用戶體驗和可訪問性的關(guān)鍵。

結(jié)構(gòu)與布局

  • 清晰的層次結(jié)構(gòu): 確保表單有一個清晰的層次結(jié)構(gòu),使用戶能夠輕松理解每個部分的目的和內(nèi)容。可以使用<fieldset><legend>來分組相關(guān)的表單元素,并且確保每個表單部分都有明確的標(biāo)題或說明。
<form id="registrationForm">
  <fieldset>
    <legend>注冊信息</legend>
    <label for="username">用戶名:</label>
    <input type="text" id="username" name="username" required>

    <label for="email">郵箱地址:</label>
    <input type="email" id="email" name="email" required>

    <label for="password">密碼:</label>
    <input type="password" id="password" name="password" required>
  </fieldset>

  <fieldset>
    <legend>聯(lián)系方式</legend>
    <label for="phone">電話號碼:</label>
    <input type="tel" id="phone" name="phone">

    <label for="address">地址:</label>
    <textarea id="address" name="address"></textarea>
  </fieldset>

  <button type="submit">提交</button>
</form>
  • 邏輯順序: 按照用戶的自然填寫順序排列表單字段,避免跳躍式布局。
<label for="firstName">名字:</label>
<input type="text" id="firstName" name="firstName" required>

<label for="lastName">姓氏:</label>
<input type="text" id="lastName" name="lastName" required>

<label for="email">郵箱地址:</label>
<input type="email" id="email" name="email" required>

標(biāo)簽

  • 使用<label>標(biāo)簽: 為每個表單控件提供明確的標(biāo)簽,以便屏幕閱讀器能夠正確讀取,可以使用for屬性將標(biāo)簽與相應(yīng)的輸入字段關(guān)聯(lián)起來。
<label for="email">郵箱地址:</label>
<input type="email" id="email" name="email" required>
  • 隱藏標(biāo)簽: 對于某些裝飾性或視覺上不必要的標(biāo)簽,可以使用CSS將其隱藏,但仍然對屏幕閱讀器可見。
<label for="search" class="sr-only">搜索:</label>
<input type="search" id="search" name="search" placeholder="搜索...">
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}

輸入字段

  • 類型提示: 使用HTML5的輸入類型提示(如emailteldate等),幫助瀏覽器提供更好的輸入體驗(如自動完成、鍵盤布局等)。
<input type="email" id="email" name="email" required>
<input type="tel" id="phone" name="phone">
<input type="date" id="birthday" name="birthday">
  • 占位符: 占位符文本可以幫助用戶了解應(yīng)該輸入的內(nèi)容,但不應(yīng)替代標(biāo)簽。
<input type="email" id="email" name="email" placeholder="example@example.com" required>

表單驗證

  • 客戶端驗證: 在用戶提交表單之前進行客戶端驗證,以防止無效數(shù)據(jù)提交,可以使用 HTML5 內(nèi)置的驗證屬性(如requiredpattern等)。
<form id="registrationForm">
  <label for="email">郵箱地址:</label>
  <input type="email" id="email" name="email" required aria-invalid="false" aria-describedby="email-error">
  <span id="email-error" class="error"></span>

  <button type="submit">提交</button>
</form>

<script>
  const form = document.getElementById('registrationForm');
  const emailInput = document.getElementById('email');
  const emailError = document.getElementById('email-error');

  form.addEventListener('submit', (e) => {
    if (!emailInput.validity.valid) {
      e.preventDefault();
      emailInput.setAttribute('aria-invalid', 'true');
      emailError.textContent = '請輸入有效的郵箱地址';
      emailInput.focus();
    }
  });
</script>
  • 服務(wù)器端驗證: 即使有客戶端驗證,仍需在服務(wù)器端進行驗證,以確保數(shù)據(jù)的安全性和完整性。

即時反饋

  • 實時驗證: 在用戶輸入過程中提供即時反饋,幫助他們在提交表單前糾正錯誤,可以使用aria-invalid屬性指示輸入的有效性狀態(tài)。
<form id="registrationForm">
  <label for="email">郵箱地址:</label>
  <input type="email" id="email" name="email" required aria-invalid="false" aria-describedby="email-error">
  <span id="email-error" class="error"></span>

  <button type="submit">提交</button>
</form>

<script>
  const emailInput = document.getElementById('email');
  const emailError = document.getElementById('email-error');

  emailInput.addEventListener('input', () => {
    if (!emailInput.validity.valid) {
      emailInput.setAttribute('aria-invalid', 'true');
      emailError.textContent = '請輸入有效的郵箱地址';
    } else {
      emailInput.setAttribute('aria-invalid', 'false');
      emailError.textContent = '';
    }
  });
</script>
  • 成功反饋: 在用戶成功提交表單后,提供明確的成功確認(rèn)信息。

輔助功能

  • ARIA屬性: 使用ARIA屬性增強表單的可訪問性,特別是在復(fù)雜交互中。

使用aria-required指示必填字段。

使用aria-describedby提供額外描述信息(如錯誤消息)。

<label for="email">郵箱地址:</label>
<input type="email" id="email" name="email" required aria-required="true" aria-describedby="email-error">
<span id="email-error" class="error"></span>
  • 鍵盤導(dǎo)航: 確保表單可以通過鍵盤操作,并且焦點管理合理。
<form id="registrationForm">
  <label for="username">用戶名:</label>
  <input type="text" id="username" name="username" required>

  <label for="email">郵箱地址:</label>
  <input type="email" id="email" name="email" required>

  <button type="submit">提交</button>
</form>

<script>
  document.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') {
      const focusedElement = document.activeElement;
      if (focusedElement.tagName.toLowerCase() === 'button') {
        focusedElement.click();
      }
    }
  });
</script>

模態(tài)框

模態(tài)框是一種常見的UI組件,用于顯示臨時信息或要求用戶進行特定操作。

HTML結(jié)構(gòu)

模態(tài)框的基本結(jié)構(gòu)應(yīng)包含一個對話框容器和關(guān)閉按鈕,并且使用適當(dāng)?shù)腁RIA屬性來定義其角色和狀態(tài)。

  • 使用role="dialog"來標(biāo)識模態(tài)框。
  • 使用aria-modal="true"來告知屏幕閱讀器這是一個模態(tài)對話框,阻止背景內(nèi)容的交互。
  • 提供明確的標(biāo)題(aria-labelledby)和描述(aria-describedby),幫助用戶理解對話框的內(nèi)容。
<div id="myModal" role="dialog" aria-modal="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" style="display: none;">
  <h2 id="modalTitle">模態(tài)標(biāo)題</h2>
  <p id="modalDescription">這是模態(tài)內(nèi)容。</p>
  <button id="closeModal">關(guān)閉</button>
</div>

焦點管理

  • 初始焦點: 當(dāng)模態(tài)框打開時,應(yīng)將焦點移動到模態(tài)框內(nèi)的第一個可聚焦元素上。如果模態(tài)框有多個可聚焦元素,選擇最相關(guān)的元素作為初始焦點。
function openModal() {
  const modal = document.getElementById('myModal');
  modal.style.display = 'block';

  // 將焦點移到關(guān)閉按鈕上
  document.getElementById('closeModal').focus();
}
  • 模態(tài)框內(nèi)焦點循環(huán):在模態(tài)框打開時,焦點應(yīng)限制在模態(tài)框內(nèi)部,防止用戶通過 Tab 鍵將焦點移出模態(tài)框,與頁面其他部分交互。可以通過第三方庫如 react-focus-lock來實現(xiàn),也可以通過監(jiān)聽keydown事件,處理Tab鍵導(dǎo)航,確保焦點始終停留在模態(tài)框內(nèi)。
function trapFocus(event) {
  const modal = document.getElementById('myModal');
  const focusableElements = modal.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
  const firstFocusableElement = focusableElements[0];
  const lastFocusableElement = focusableElements[focusableElements.length - 1];

  if (event.shiftKey && document.activeElement = firstFocusableElement) {
    // Shift + Tab 從第一個元素移出
    lastFocusableElement.focus();
    event.preventDefault();
  } else if (!event.shiftKey && document.activeElement = lastFocusableElement) {
    // Tab 從最后一個元素移出
    firstFocusableElement.focus();
    event.preventDefault();
  }
}

document.addEventListener('keydown', trapFocus);
  • 關(guān)閉模態(tài)框時恢復(fù)焦點:當(dāng)模態(tài)框關(guān)閉時,應(yīng)將焦點恢復(fù)到打開模態(tài)框的觸發(fā)元素上,以便用戶可以繼續(xù)之前的操作。
const closeModalButton = document.getElementById('close-modal');
closeModalButton.addEventListener('click', () => {
    modal.hidden = true;
    openModalButton.focus();
});

樣式與視覺提示

  • 視覺焦點指示: 為可聚焦元素提供清晰的視覺焦點指示,幫助視力障礙者識別當(dāng)前聚焦的位置。
button:focus, input:focus, select:focus, textarea:focus {
  outline: 2px solid #007bff;
  outline-offset: 2px;
}
  • 背景遮罩: 使用背景遮罩來模糊或隱藏背景內(nèi)容,使模態(tài)框更加突出,背景遮罩應(yīng)覆蓋整個視口,并具有一定的透明度。
<div id="overlay" style="display: none;"></div>
<div id="myModal" role="dialog" aria-modal="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" style="display: none;">
  <!-- 模態(tài)框內(nèi)容 -->
</div>

<style>
  #overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 9998;
  }

  #myModal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: white;
    padding: 20px;
    z-index: 9999;
  }
</style>

<script>
  function openModal() {
    const overlay = document.getElementById('overlay');
    const modal = document.getElementById('myModal');

    overlay.style.display = 'block';
    modal.style.display = 'block';

    // 將焦點移到關(guān)閉按鈕上
    document.getElementById('closeModal').focus();
  }

  function closeModal() {
    const overlay = document.getElementById('overlay');
    const modal = document.getElementById('myModal');

    overlay.style.display = 'none';
    modal.style.display = 'none';

    // 恢復(fù)之前的焦點
    if (previousActiveElement) {
      previousActiveElement.focus();
    }
  }
</script>

小結(jié):可訪問性不是功能,而是責(zé)任。通過實現(xiàn)這些技術(shù)細節(jié),我們不僅滿足 WCAG 標(biāo)準(zhǔn),更是為所有用戶構(gòu)建真正的包容性網(wǎng)絡(luò)。從下一個功能需求開始,將可訪問性刻進你的開發(fā) DNA。

責(zé)任編輯:武曉燕 來源: 前端充電寶
相關(guān)推薦

2021-01-12 14:37:09

開發(fā)科學(xué)寫作

2017-06-01 11:55:45

混合云連接云計算

2022-10-09 08:16:29

React前端

2019-06-06 15:49:53

多線程iOS開發(fā)操作

2025-05-15 00:01:00

2020-03-03 10:17:00

云計算公共云

2013-09-17 13:24:07

Unix操作系統(tǒng)

2023-10-25 13:37:04

Git

2020-05-17 16:19:59

JavaScript代碼開發(fā)

2009-04-24 10:57:25

2024-03-28 16:05:26

2009-06-19 11:38:15

JavaFX 1.2

2017-07-05 16:15:00

2018-05-18 15:05:25

JavaJava 10新特性

2022-03-31 14:28:43

數(shù)據(jù)安全企業(yè)數(shù)據(jù)保護

2014-05-05 09:58:01

2012-06-13 01:05:53

JavaRubyJVM

2020-07-17 09:58:31

Python開發(fā)工具

2013-11-14 10:06:10

2009-04-24 14:56:24

點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 日韩精品一区二区三区在线播放 | 看a级黄色毛片 | 国产精品成人一区二区三区 | 成人av一区 | 久久国产婷婷国产香蕉 | 视频一区二区三区在线观看 | 国产精品日日做人人爱 | 久草热8精品视频在线观看 午夜伦4480yy私人影院 | 欧美午夜一区二区三区免费大片 | 国产特黄一级 | 男女黄网站| 欧美一区二区三区在线观看 | 国产成人av在线播放 | 天天操夜夜操免费视频 | 精品在线一区二区三区 | 亚洲精品视频一区 | 69av网| 国产日韩欧美 | 91精品国产综合久久久久 | 欧美三级在线 | 日韩精品免费一区 | 久久av一区 | 日韩欧美一区二区三区免费观看 | 亚洲天堂免费 | 狠狠操狠狠操 | 国产亚洲一区二区三区 | 久草热线| 蜜桃精品视频在线 | 婷婷毛片| 亚洲电影成人 | 91久久爽久久爽爽久久片 | 欧美激情久久久 | 日韩在线播放中文字幕 | 成人免费淫片aa视频免费 | 欧美日韩国产在线观看 | 成人字幕网zmw | 免费黄色片在线观看 | 欧美精品网站 | av大片| 青青草视频免费观看 | 亚洲乱码一区二区三区在线观看 |