Developer Tools

Web Accessibility (a11y): คู่มือปฏิบัติสำหรับนักพัฒนา

เรียนรู้หลักการ accessibility ที่จำเป็น, ARIA attributes, รูปแบบการนำทางด้วยคีย์บอร์ด และเครื่องมือทดสอบที่ทำให้เว็บแอปของคุณใช้งานได้สำหรับทุกคน

8 นาทีในการอ่าน

Person using a laptop with assistive technology

มากกว่า 1.3 พันล้านคน — หรือ 16% ของประชากรโลก — ใช้ชีวิตอยู่กับความพิการในรูปแบบใดรูปแบบหนึ่ง Web accessibility ช่วยให้เว็บไซต์ของคุณรองรับผู้ใช้ที่พึ่งพา screen reader, การนำทางด้วยคีย์บอร์ด, switch access หรือเทคโนโลยีช่วยเหลืออื่นๆ นอกจากการส่งเสริมความเท่าเทียม เว็บไซต์ที่เข้าถึงได้ยังติดอันดับการค้นหาได้ดีกว่า ทำงานได้ดีกว่าบนมือถือ และมักเป็นข้อกำหนดทางกฎหมายด้วย

หลักการ POUR ทั้งสี่ข้อ

Web Content Accessibility Guidelines (WCAG) สร้างขึ้นบนหลักการสำคัญสี่ข้อ เนื้อหาต้อง:

  1. Perceivable (รับรู้ได้) — ข้อมูลต้องนำเสนอในรูปแบบที่ผู้ใช้สามารถรับรู้ได้ (ไม่ใช่แค่ทางสายตา)
  2. Operable (ใช้งานได้) — ฟังก์ชันทั้งหมดต้องใช้งานได้ผ่านคีย์บอร์ด
  3. Understandable (เข้าใจได้) — เนื้อหาและ interface ต้องเข้าใจง่าย
  4. Robust (แข็งแกร่ง) — เนื้อหาต้องถูก parse ได้โดยเทคโนโลยีช่วยเหลือ

WCAG 2.2 กำหนดระดับการปฏิบัติตามไว้สามระดับ:

  • A — ขั้นต่ำ (สิ่งที่ต้องมี)
  • AA — เป้าหมายมาตรฐานสำหรับองค์กรส่วนใหญ่
  • AAA — สูงสุด (เป็นเป้าหมายสำหรับเนื้อหาบางประเภท)

ข้อกำหนดทางกฎหมายส่วนใหญ่ (ADA, EN 301 549, EAA) กำหนดให้ต้องเป็นไปตาม AA conformance

เริ่มจาก Semantic HTML

สิ่งที่ส่งผลต่อ accessibility มากที่สุดคือการใช้ HTML element ที่ถูกต้องสำหรับแต่ละงาน เบราว์เซอร์และ screen reader รู้อยู่แล้วว่าต้องจัดการกับ semantic element อย่างไร:

<!-- ❌ Div soup — no semantics -->
<div class="header">
  <div class="nav">
    <div class="nav-item" onclick="navigate()">Home</div>
  </div>
</div>

<!-- ✅ Semantic HTML — screen readers understand this -->
<header>
  <nav>
    <a href="/">Home</a>
  </nav>
</header>

Semantic element สำคัญและบทบาทของแต่ละตัว:

Element บทบาท
<header>, <footer> Landmark regions
<nav> Navigation landmark
<main> เนื้อหาหลัก (หนึ่งอันต่อหน้า)
<aside> เนื้อหาเสริม
<h1><h6> ลำดับชั้นของหัวข้อ
<button> Interactive control
<a href> Navigation link
<label> ป้ายกำกับช่องฟอร์ม
<table> ข้อมูลแบบตาราง

รูปภาพและ alt text

รูปภาพที่มีความหมายทุกรูปต้องมี attribute alt ที่อธิบายเนื้อหา รูปภาพที่เป็นการตกแต่งเพียงอย่างเดียวให้ใส่ alt="" เพื่อให้ screen reader ข้ามผ่านไป:

<!-- Meaningful image -->
<img src="chart.png" alt="Bar chart showing 40% increase in revenue Q1 2026">

<!-- Decorative image -->
<img src="divider.svg" alt="">

<!-- Icon button — describe the action, not the icon -->
<button>
  <img src="trash.svg" alt="Delete item">
</button>

<!-- Avoid: redundant "image of" -->
<!-- ❌ --> <img src="cat.jpg" alt="Image of a cat">
<!-- ✅ --> <img src="cat.jpg" alt="Orange tabby cat sitting on a windowsill">

Color contrast

ผู้ใช้ที่มีสายตาเลือนรางหรือตาบอดสีต้องพึ่งพาความแตกต่างของสีระหว่างตัวอักษรและพื้นหลังที่เพียงพอ

ข้อกำหนด WCAG AA:

  • ตัวอักษรทั่วไป (< 18pt): อัตราส่วน contrast ขั้นต่ำ 4.5:1
  • ตัวอักษรขนาดใหญ่ (≥ 18pt หรือ 14pt ตัวหนา): อัตราส่วน contrast ขั้นต่ำ 3:1
  • UI components และองค์ประกอบกราฟิก: ขั้นต่ำ 3:1

อย่าใช้สีเพียงอย่างเดียวในการสื่อข้อมูล:

<!-- ❌ Color-only status indicator -->
<span class="text-red-500">Error</span>

<!-- ✅ Color + icon + text -->
<span class="text-red-500 flex items-center gap-1">
  <svg aria-hidden="true"><!-- error icon --></svg>
  Error: Invalid email address
</span>

ฟอร์ม: labels, errors และ descriptions

ทุก form control ต้องมี label ที่มองเห็นได้และเชื่อมโยงกันอย่างถูกต้อง:

<!-- ✅ Explicit label association -->
<label for="email">Email address</label>
<input id="email" type="email" aria-describedby="email-hint email-error">
<p id="email-hint" class="text-sm text-gray-500">We'll never share your email.</p>
<p id="email-error" role="alert" class="text-sm text-red-600" hidden>
  Please enter a valid email address.
</p>

รูปแบบสำคัญสำหรับ form accessibility:

  • ใช้ for/id เพื่อเชื่อม label กับ input
  • ใช้ aria-describedby สำหรับข้อความคำแนะนำและข้อความแสดงข้อผิดพลาด
  • ใช้ role="alert" หรือ aria-live="polite" สำหรับข้อความแสดงข้อผิดพลาดแบบ dynamic
  • ใช้ aria-required="true" หรือ attribute required แบบ native
  • จัดกลุ่ม input ที่เกี่ยวข้องด้วย <fieldset> และ <legend>

การนำทางด้วยคีย์บอร์ด

ทุก interactive element ต้องสามารถเข้าถึงและใช้งานได้ด้วยคีย์บอร์ด:

  • Tab — เลื่อนไปข้างหน้าระหว่าง element ที่รับ focus ได้
  • Shift+Tab — เลื่อนถอยหลัง
  • Enter/Space — เปิดใช้งาน button, checkbox
  • Arrow keys — นำทางภายใน component (เมนู, แท็บ, slider)
  • Escape — ปิด modal, ยกเลิก dropdown

Focus indicator ต้องมองเห็นได้ ห้ามทำสิ่งนี้โดยไม่มีทางเลือกอื่น:

/* ❌ Hides focus indicator entirely */
*:focus { outline: none; }

/* ✅ Custom focus style that's still visible */
*:focus-visible {
  outline: 2px solid #3b82f6;
  outline-offset: 2px;
}

ARIA: เมื่อไหร่และอย่างไรที่ควรใช้

ARIA (Accessible Rich Internet Applications) attributes เพิ่ม semantic meaning เมื่อ HTML อย่างเดียวไม่เพียงพอ กฎข้อแรกของ ARIA: อย่าใช้ ARIA ถ้า native HTML ทำได้

<!-- Labeling elements without visible labels -->
<button aria-label="Close dialog">✕</button>

<!-- Describing expanded state -->
<button aria-expanded="false" aria-controls="menu">Menu</button>
<ul id="menu" hidden>...</ul>

<!-- Live region for dynamic content -->
<div aria-live="polite" aria-atomic="true">
  <!-- Screen readers announce changes to this area -->
  3 results found
</div>

<!-- Landmark role when semantic element isn't available -->
<div role="search">
  <input type="search" placeholder="Search...">
</div>

การจัดการ Focus สำหรับ SPA และ Modal

ใน single-page application การนำทางระหว่างหน้าไม่ได้ทำให้เบราว์เซอร์รีเซ็ต focus โดยอัตโนมัติ เมื่อ "หน้า" โหลดขึ้นมา ให้ย้าย focus ไปยังตำแหน่งที่มีความหมาย:

// After navigation, focus the main heading
document.querySelector("h1")?.focus();

สำหรับ modal:

  1. เมื่อ modal เปิด ให้ย้าย focus ไปยัง element แรกที่รับ focus ได้ภายใน modal
  2. ขัง focus ไว้ภายใน modal ขณะที่เปิดอยู่ (ป้องกันไม่ให้ Tab ไปถึงเนื้อหาด้านหลัง)
  3. เมื่อ modal ปิด ให้คืน focus ไปยัง element ที่เปิด modal นั้น

การทดสอบ Accessibility

เครื่องมืออัตโนมัติ (ตรวจพบปัญหาได้ประมาณ 30-40%)

  • axe DevTools browser extension
  • Lighthouse accessibility audit ใน Chrome DevTools
  • WAVE browser extension

การทดสอบด้วยตัวเอง (จำเป็นสำหรับการครอบคลุมที่สมบูรณ์)

  1. การนำทางด้วยคีย์บอร์ดเพียงอย่างเดียว — ถอดเมาส์ออกและลองนำทางทั้งเว็บไซต์
  2. การทดสอบด้วย screen reader — NVDA + Firefox (Windows), VoiceOver + Safari (Mac/iOS)
  3. ซูมที่ 200% — ตรวจสอบว่าไม่มีเนื้อหาหายไปหรือทับซ้อนกัน
  4. การจำลองตาบอดสี — browser DevTools → Rendering → Emulate vision deficiencies

ความสามารถในการอ่าน

ภาษาที่เข้าใจง่ายช่วยเพิ่ม accessibility สำหรับผู้ใช้ที่มีความบกพร่องทางการรับรู้ ใช้เครื่องมือ Readability Score ของเราเพื่อตรวจสอบระดับการอ่านของเนื้อหา — เป้าหมายควรอยู่ที่ระดับ Grade 8-10 สำหรับผู้ชมทั่วไป

สิ่งที่ทำได้ทันทีเพื่อผลลัพธ์ที่รวดเร็ว

  1. เพิ่ม alt text ให้กับรูปภาพทั้งหมด
  2. ตรวจสอบว่า form input ทุกตัวมี element <label> เชื่อมโยงอยู่
  3. ตรวจสอบว่า color contrast ของตัวอักษรในเนื้อหาได้มาตรฐาน 4.5:1
  4. เพิ่ม style สำหรับ :focus-visible และอย่าลบ outline ออกโดยไม่มีสิ่งทดแทน
  5. ใช้ <button> สำหรับ action และ <a href> สำหรับการนำทาง (ห้ามสลับกัน)
  6. เพิ่ม lang="en" (หรือภาษาที่เหมาะสม) ใน element <html> ของคุณ
  7. ใช้ <h1> หนึ่งอันต่อหน้า และรักษาลำดับชั้นของหัวข้อให้สมเหตุสมผล

Accessibility ไม่ใช่ส่วนเสริม — มันคือคุณลักษณะด้านคุณภาพ การสร้างผลิตภัณฑ์ที่เข้าถึงได้ตั้งแต่ต้นนั้นถูกกว่าการแก้ไขทีหลังมาก และยังทำให้ผลิตภัณฑ์ของคุณดีขึ้นสำหรับทุกคนด้วย