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

被多數前端開發忽略的重要特性!

開發 前端
可訪問性不是功能,而是責任。通過實現這些技術細節,我們不僅滿足 WCAG 標準,更是為所有用戶構建真正的包容性網絡。從下一個功能需求開始,將可訪問性刻進你的開發 DNA。

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

圖片

可訪問性是什么?

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

Web 可訪問性的重要性:

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

WCAG

WCAG(Web Content Accessibility Guidelines,網頁內容可訪問性指南)是由 W3C(萬維網聯盟)制定的國際標準,旨在確保網頁內容對所有人均可訪問和使用。

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

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

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

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

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

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

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

圖片

可訪問性的前端實現

Web 可訪問性需要貫穿開發全流程,從前端技術實現到設計協作,再到測試驗證。

語義化HTML

根據內容的含義選擇合適的 HTML 標簽,這有助于屏幕閱讀器等輔助技術理解頁面結構,方便用戶導航。

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

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

常見的語義化標簽包括:

標簽

作用

<header>

定義文檔或節的頁眉,包含介紹性內容,如網站標志、標題、導航欄等

<nav>

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

<main>

規定文檔的主要內容,該內容應獨一無二,不包含重復出現的內容

<article>

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

<section>

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

<aside>

定義所處內容之外的內容,常表現為側邊欄或插入內容,與周圍內容相關但非主要部分

<footer>

定義文檔或節的頁腳,包含版權信息、作者信息、聯系方式等

<h1> - <h6>

定義不同級別的標題,構建文檔大綱結構,利于搜索引擎理解及用戶瀏覽

<ul>

創建無序列表,列表項無特定順序,以項目符號顯示

<ol>

創建有序列表,列表項按數字或字母順序排列,適用于強調順序的內容

<dl>

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

<blockquote>

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

<q>

定義短的行內引用,瀏覽器自動在兩端加引號

<time>

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

語義化 HTML 的好處:

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

鍵盤導航

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

可聚焦元素

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

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

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

焦點順序

  • 自然順序:鍵盤焦點的移動順序應該與網頁內容的邏輯和視覺順序一致。通常,焦點會按照 HTML 文檔中元素出現的先后順序進行移動。例如,在一個表單中,焦點會從第一個輸入框開始,依次移動到后續的輸入框、按鈕等元素。
  • 調整順序:在某些情況下,可能需要調整焦點順序??梢允褂?tabindex 屬性來實現。

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

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

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

焦點可見性

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

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

注意事項:

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

鍵盤操作支持

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

跳過導航

對于一些大型網頁,可能存在大量的導航鏈接和重復的內容,用戶可能希望快速跳過這些內容,直接訪問主要內容。這時可以提供 “跳過導航” 鏈接。

實現方法:在頁面頂部添加一個隱藏的鏈接,當用戶使用鍵盤將焦點移動到該鏈接時,鏈接顯示出來,用戶按下 Enter 鍵可以直接跳轉到頁面的主要內容區域。

<a href="#main-content" class="skip-nav">跳過導航</a>
<header>
    <nav>
        <ul>
            <li><a href="#">首頁</a></li>
            <li><a href="#">產品</a></li>
            <li><a href="#">關于我們</a></li>
        </ul>
    </nav>
</header>
<main id="main-content">
    <h1>主要內容標題</h1>
    <p>主要內容文本...</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;
}

這樣,當用戶使用鍵盤將焦點移動到該鏈接時,鏈接會顯示出來,按下 Enter 鍵可以直接跳轉到頁面的主要內容區域。

測試驗證

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

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

Shift + Tab:測試反向導航,確保焦點順序正確。

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

Esc鍵:測試模態對話框、下拉菜單等是否可以通過Esc鍵關閉。

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

ARIA 屬性

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

ARIA 屬性主要分為三類:角色、狀態、屬性。

角色

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

  • role="button":將一個普通的 <div> 元素定義為按鈕,使其具有按鈕的語義。
<div role="button" tabindex="0">前端充電寶</div>
  • role="menu"role="menuitem":用于創建自定義菜單,明確菜單和菜單項的角色。
<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>標題</h2>
  <p>內容</p>
  <button id="closeDialog">關閉</button>
</div>

注意事項:

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

狀態

狀態表示元素當前的狀態,如是否選中、是否展開等。常見的狀態包括aria-checked、aria-expanded等。

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

屬性

屬性提供了額外的信息,如標簽、描述等。常見的屬性包括aria-label、aria-labelledby、aria-describedby等。

  • aria-label:為元素提供一個明確的標簽,用于替代元素內部的文本,特別是當元素沒有可見文本時,適用于簡單的替代文本。
<input type="search" aria-label="搜索框">
<button aria-label="關閉菜單">X</button>
  • aria-labelledby:引用其他元素的ID作為標簽來源,適用于引用現有文本作為標簽的情況。
<h1 id="page-title">網站</h1>
<nav aria-labelledby="page-title">
  <ul>
    <li><a href="#home">首頁</a></li>
    <li><a href="#about">關于我們</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>

多媒體內容

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

圖片可訪問性

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

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

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

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

視頻可訪問性

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

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

  // 添加鍵盤事件監聽器
  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>

音頻可訪問性

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

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

  // 添加鍵盤事件監聽器
  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>

整體策略

  • 自動播放限制: 避免自動播放多媒體內容,特別是帶有聲音的視頻或音頻,以免干擾用戶的體驗??梢允褂?code style="background-color: rgb(231, 243, 237); padding: 1px 3px; border-radius: 4px; overflow-wrap: break-word; text-indent: 0px; display: inline-block;">preload="none"或preload="metadata"來延遲加載視頻,直到用戶明確請求播放。
<video controls preload="none">
  <source src="example.mp4" type="video/mp4">
</video>
  • 焦點管理: 確保當多媒體內容加載或動態更新時,焦點正確管理,不會導致用戶失去當前的操作上下文。

表單設計

設計一個易于理解和使用的表單是提升用戶體驗和可訪問性的關鍵。

結構與布局

  • 清晰的層次結構: 確保表單有一個清晰的層次結構,使用戶能夠輕松理解每個部分的目的和內容??梢允褂?code style="background-color: rgb(231, 243, 237); padding: 1px 3px; border-radius: 4px; overflow-wrap: break-word; text-indent: 0px; display: inline-block;"><fieldset>和<legend>來分組相關的表單元素,并且確保每個表單部分都有明確的標題或說明。
<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>聯系方式</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>

標簽

  • 使用<label>標簽: 為每個表單控件提供明確的標簽,以便屏幕閱讀器能夠正確讀取,可以使用for屬性將標簽與相應的輸入字段關聯起來。
<label for="email">郵箱地址:</label>
<input type="email" id="email" name="email" required>
  • 隱藏標簽: 對于某些裝飾性或視覺上不必要的標簽,可以使用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">
  • 占位符: 占位符文本可以幫助用戶了解應該輸入的內容,但不應替代標簽。
<input type="email" id="email" name="email" placeholder="example@example.com" required>

表單驗證

  • 客戶端驗證: 在用戶提交表單之前進行客戶端驗證,以防止無效數據提交,可以使用 HTML5 內置的驗證屬性(如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>
  • 服務器端驗證: 即使有客戶端驗證,仍需在服務器端進行驗證,以確保數據的安全性和完整性。

即時反饋

  • 實時驗證: 在用戶輸入過程中提供即時反饋,幫助他們在提交表單前糾正錯誤,可以使用aria-invalid屬性指示輸入的有效性狀態。
<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>
  • 成功反饋: 在用戶成功提交表單后,提供明確的成功確認信息。

輔助功能

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

使用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>
  • 鍵盤導航: 確保表單可以通過鍵盤操作,并且焦點管理合理。
<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>

模態框

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

HTML結構

模態框的基本結構應包含一個對話框容器和關閉按鈕,并且使用適當的ARIA屬性來定義其角色和狀態。

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

焦點管理

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

  // 將焦點移到關閉按鈕上
  document.getElementById('closeModal').focus();
}
  • 模態框內焦點循環:在模態框打開時,焦點應限制在模態框內部,防止用戶通過 Tab 鍵將焦點移出模態框,與頁面其他部分交互??梢酝ㄟ^第三方庫如 react-focus-lock來實現,也可以通過監聽keydown事件,處理Tab鍵導航,確保焦點始終停留在模態框內。
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);
  • 關閉模態框時恢復焦點:當模態框關閉時,應將焦點恢復到打開模態框的觸發元素上,以便用戶可以繼續之前的操作。
const closeModalButton = document.getElementById('close-modal');
closeModalButton.addEventListener('click', () => {
    modal.hidden = true;
    openModalButton.focus();
});

樣式與視覺提示

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

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

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

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

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

小結:可訪問性不是功能,而是責任。通過實現這些技術細節,我們不僅滿足 WCAG 標準,更是為所有用戶構建真正的包容性網絡。從下一個功能需求開始,將可訪問性刻進你的開發 DNA。

責任編輯:武曉燕 來源: 前端充電寶
相關推薦

2021-01-12 14:37:09

開發科學寫作

2017-06-01 11:55:45

混合云連接云計算

2022-10-09 08:16:29

React前端

2019-06-06 15:49:53

多線程iOS開發操作

2025-05-15 00:01:00

2020-03-03 10:17:00

云計算公共云

2013-09-17 13:24:07

Unix操作系統

2023-10-25 13:37:04

Git

2020-05-17 16:19:59

JavaScript代碼開發

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新特性

2014-05-05 09:58:01

2022-03-31 14:28:43

數據安全企業數據保護

2012-06-13 01:05:53

JavaRubyJVM

2020-07-17 09:58:31

Python開發工具

2013-11-14 10:06:10

2009-04-24 14:56:24

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品亚洲综合 | 在线视频一区二区 | 在线亚洲免费 | a免费视频| 国产精品视频网 | 尤物在线精品视频 | 亚洲黄色在线免费观看 | 一区二区国产精品 | 欧美激情综合色综合啪啪五月 | 久久久亚洲成人 | 亚洲传媒在线 | 精品三级在线观看 | 亚洲一区二区三区免费视频 | 日韩欧美在线观看视频 | 91久久看片 | 97人人草| 国产91一区| 国产精品美女在线观看 | 日韩精品一区二区三区中文在线 | 最新中文字幕在线 | 天天干天天插天天 | 中文字幕日韩欧美一区二区三区 | 成人精品网| 久久一区| 亚洲成人免费视频 | 国产精品成人久久久久 | 精品色| 亚洲网站在线观看 | 亚洲成人精品影院 | 在线国产小视频 | 久久亚洲视频 | 国产综合精品 | 激情欧美一区二区三区中文字幕 | 日韩免费毛片 | 国产九九九九 | 久久噜| 成人免费视频网站在线看 | 国产精品欧美一区二区三区不卡 | 蜜桃在线一区二区三区 | 日韩在线视频免费观看 | 免费在线观看av网址 |