Content Description คือคุณสมบัติการเข้าถึงที่ส่งคำอธิบายที่เป็นข้อความของเนื้อหาที่ไม่ใช่ข้อความไปยังเทคโนโลยีช่วยเหลือ ใน iOS คือแอตทริบิวต์ accessibilityHint สำหรับ UIView ใน Android คือ contentDescription ในมาร์กอัป XML ตาม W3C WCAG 2.2, 2023 การไม่มีทางเลือกข้อความสำหรับเนื้อหาที่ไม่ใช่ข้อความเป็นหนึ่งในการละเมิดการเข้าถึงที่พบบ่อยที่สุดในแอปพลิเคชันมือถือ คำอธิบายที่กรอกอย่างถูกต้องทำให้แอปสามารถเข้าถึงได้สำหรับผู้ที่มีความบกพร่องทางการมองเห็นที่ใช้ VoiceOver และ TalkBack
ประเด็นสำคัญ
Content Description คือคุณสมบัติสตริงขององค์ประกอบอินเทอร์เฟซที่ให้การแสดงเนื้อหาที่เป็นข้อความของเนื้อหาที่มองเห็นแก่เทคโนโลยีช่วยเหลือ โปรแกรมอ่านหน้าจอ (VoiceOut ใน iOS, TalkBack ใน Android) อ่านคำอธิบายออกเสียงแทนที่จะพยายามรู้จำองค์ประกอบด้วยสายตา คำอธิบายใช้กับรูปภาพที่ไม่มีชั้นข้อความ ไอคอน แผนภูมิ ตัวควบคุมที่กำหนดเอง และองค์ประกอบที่ไม่ใช่ข้อความทั้งหมด
ตาม Google Material Design, 2024 องค์ประกอบที่ไม่มี contentDescription ละเมิด WCAG 1.1.1 (Non-text Content) การตรวจสอบของ Accessibility Scanner แสดงว่าไอคอนสูงสุด 40% ในแอปช้อปปิ้งไม่มีคำอธิบาย ผู้ใช้ VoiceOver ได้ยินเพียง “รูปภาพ” หรือ “ปุ่ม” โดยไม่มีรายละเอียด — อินเทอร์เฟซดังกล่าวไม่สามารถใช้งานได้สำหรับการนำทาง
Content Description ไม่ได้แทนที่ข้อความที่มองเห็นขององค์ประกอบ หากปุ่มมีป้ายข้อความ “ส่ง” ไม่จำเป็นต้องตั้งคำอธิบายเพิ่มเติม — โปรแกรมอ่านหน้าจอจะอ่านข้อความ สำหรับรูปภาพ ไอคอน และฟิลด์ป้อนข้อมูล คำอธิบายเป็นสิ่งจำเป็น
เครื่องมือ Accessibility Scanner (Android) และ Xcode Accessibility Inspector (iOS) จะตรวจสอบการมีอยู่ของคำอธิบายโดยอัตโนมัติ ขอแนะนำให้เรียกใช้การตรวจสอบเหล่านี้บนทุกหน้าจอก่อนเผยแพร่
ผู้ใช้ที่ มีความบกพร่องทางการมองเห็น อาศัย VoiceOver เพื่อทำความเข้าใจอินเทอร์เฟซ หากไอคอนตะกร้าสินค้าไม่มีคำอธิบาย เขาจะได้ยินเพียง “ปุ่ม” เพื่อค้นหาว่าปุ่มทำอะไร เขาต้องกดโดยไม่เห็น — เสี่ยงต่อการกระทำที่ไม่อาจย้อนกลับ คำอธิบายเช่น “ลบรายการออกจากตะกร้า” แก้ปัญหานี้ได้ในหนึ่งวินาที
ผู้ใช้ที่มี ข้อจำกัดชั่วคราว (แดดจ้ากลางแจ้ง หน้าจอแตก) ก็ใช้ VoiceOver เช่นกัน ตาม Apple Accessibility Report, 2023 ประมาณ 20% ของผู้ใช้ VoiceOver ไม่มีความบกพร่องทางการมองเห็นถาวร — พวกเขาเปิดฟีเจอร์ตามสถานการณ์
เกณฑ์ WCAG 1.1.1 (ระดับ A) กำหนดว่าเนื้อหาที่ไม่ใช่ข้อความทั้งหมดต้องมีทางเลือกที่เป็นข้อความ ข้อยกเว้น: เนื้อหาที่ใช้ตกแต่ง ใช้เพื่อการนำเสนอด้วยภาพเท่านั้น หรือไม่สื่อข้อมูล การทดสอบการตกแต่ง: หากคุณลบองค์ประกอบ ความหมายของหน้าเปลี่ยนแปลงหรือไม่ ถ้าไม่ — สามารถซ่อนจากโปรแกรมอ่านหน้าจอได้
Accessibility Label (accessibilityLabel ใน iOS) คือชื่อขององค์ประกอบที่โปรแกรมอ่านหน้าจอพูดเมื่อได้รับโฟกัส Content Description (accessibilityHint ใน iOS) คือคำชี้แจงเพิ่มเติมที่ประกาศหลังจากชื่อและบอกผลลัพธ์ของการกระทำ
ความแตกต่างชัดเจนด้วยตัวอย่าง ปุ่ม “ตะกร้า” Label: “ตะกร้า” Description: “จะเปิดหน้าจอชำระเงิน” VoiceOver พูด: “ตะกร้า จะเปิดหน้าจอชำระเงิน” หากตั้งค่าเฉพาะ Label ผู้ใช้จะไม่รู้ว่าจะเกิดอะไรขึ้นหลังจากกด
| คุณสมบัติ | iOS | Android | วัตถุประสงค์ |
|---|---|---|---|
| Label | accessibilityLabel | contentDescription | ชื่อขององค์ประกอบ (ปุ่ม, ฟิลด์, รูปภาพ) |
| Description | accessibilityHint | contentDescription (ขยาย) | คำชี้แจงของการกระทำหรือความหมาย |
| Trait | accessibilityTraits | role / className | บทบาทขององค์ประกอบ (ปุ่ม, หัวเรื่อง) |
กฎ: Label ตอบคำถาม “นี่คืออะไร?”, Description ตอบ “จะเกิดอะไรขึ้น?” ใน Android contentDescription สามารถทำหน้าที่ทั้งสองได้ แต่ในทางปฏิบัติควรแยกออกจากกัน: ใช้การต่อ “[ชื่อ], [คำอธิบาย]”
สำหรับ ท่าทางที่ซับซ้อน (ปัดเพื่อลบ กดค้างเพื่อเมนูบริบท) accessibilityHint เป็นสิ่งจำเป็น ผู้ใช้ VoiceOver ไม่รู้เกี่ยวกับท่าทางที่ซ่อนอยู่เว้นแต่จะมีการอธิบาย ระบุ: “ปัดไปทางซ้ายเพื่อลบ” ใน hint ขององค์ประกอบ
บนแพลตฟอร์ม iOS accessibilityHint ถูกตั้งค่าผ่านคุณสมบัติชื่อเดียวกันของ UIView หรือ NSObject ค่าเป็นสตริงสูงสุด 80 ตัวอักษร VoiceOver อ่าน hint หลังจาก label เมื่อเปิดโหมดคำอธิบายโดยละเอียด (ในการตั้งค่า VoiceOver — “Verbosity”)
ตัวอย่างการตั้งค่า hint สำหรับปุ่มที่กำหนดเอง:
import UIKit
class CustomButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.accessibilityLabel = "เพิ่มในรายการโปรด"
self.accessibilityHint = "จะบันทึกรายการในรายการโปรด"
}
}
สำหรับ UIImageView ที่ไม่มีเนื้อหาข้อความ จำเป็นต้องตั้งค่า isAccessibilityElement = true และ accessibilityHint:
let imageView = UIImageView(image: UIImage(named: "chart-sales"))
imageView.isAccessibilityElement = true
imageView.accessibilityHint = "แผนภูมิยอดขายสำหรับไตรมาสล่าสุด"
VoiceOver อ่าน: “แผนภูมิยอดขายสำหรับไตรมาสล่าสุด” หาก hint ว่าง — เพียง “รูปภาพ” Apple HIG, 2024 แนะนำไม่ให้ใช้คำกริยาเช่น “แตะ” หรือ “กด” ใน hint — VoiceOver เพิ่มคำแนะนำท่าทางโดยอัตโนมัติ
ใน SwiftUI hint ถูกตั้งค่าผ่านตัวปรับเปลี่ยนแบบลูกโซ่:
Image(systemName: "trash")
.accessibilityLabel("ลบ")
.accessibilityHint("จะลบรายการที่เลือกอย่างถาวร")
SwiftUI รวม ตัวปรับเปลี่ยนสำหรับวิวประกอบโดยอัตโนมัติ หาก Image อยู่ภายใน Button SwiftUI จะใช้ป้ายของปุ่มเป็น accessibilityLabel หลัก
ใน Android contentDescription ถูกตั้งค่าในมาร์กอัป XML หรือโดยโปรแกรมผ่าน setContentDescription() TalkBack ประกาศคำอธิบายเมื่อองค์ประกอบได้รับโฟกัส
ตัวอย่างใน XML:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_search"
android:contentDescription="ค้นหาสินค้า" />
การตั้งค่าโดยโปรแกรมสำหรับองค์ประกอบแบบไดนามิก:
binding.iconSearch.contentDescription =
"ค้นหา จะเปิดหน้าจอค้นหาด้วยตัวกรอง"
สำหรับ รูปภาพตกแต่ง (ตัวคั่น, พื้นหลัง, ไอคอนตกแต่ง) ให้ตั้งค่า contentDescription = "@null" หรือ setContentDescription(null) — TalkBack จะข้ามองค์ประกอบเหล่านี้ ใน XML: android:contentDescription="@null" สตริงว่าง "" ใช้ไม่ได้ — TalkBack จะยังคงประกาศ “รูปภาพ”
สำหรับ ImageButton ให้ตั้งค่า contentDescription เสมอ — TalkBack ไม่เห็นข้อความบนรูปภาพ สำหรับ CheckBox คำอธิบายควรเปลี่ยนแบบไดนามิก: “เลือกแล้ว” / “ไม่ได้เลือก” แทนคำอธิบายคงที่ ใช้ setContentDescription ในตัวฟังสถานะ
ความให้ข้อมูล — คำอธิบายควรสื่อความหมาย ไม่ใช่รูปลักษณ์ ไม่ใช่ “ไอคอนสีน้ำเงินมีเครื่องหมายถูก” แต่เป็น “เพิ่มรายการในตะกร้าแล้ว” โปรแกรมอ่านหน้าจอไม่สนใจสี — มันสนใจผลลัพธ์
ความกระชับ — ความยาวที่เหมาะสมคือ 2–4 คำ (สูงสุด 80 ตัวอักษร) คำอธิบายยาวทำให้การนำทางช้าลง: VoiceOver อ่านตามลำดับ แต่ละคำคือหนึ่งวินาทีของเวลาผู้ใช้ ตาม Apple WWDC 2023, “Accessibility by Design” วลีที่ใช้เวลาอ่านเกิน 5 วินาทีจะขัดขวางกระแสความคิด
ความเป็นเอกลักษณ์ — ไม่ควรมีสององค์ประกอบบนหน้าจอเดียวกันที่มีคำอธิบายเหมือนกัน ผู้ใช้จะไม่สามารถแยกได้ว่าการโฟกัสที่องค์ประกอบแรกกับองค์ประกอบที่สองจะให้ผลลัพธ์ต่างกันอย่างไร หากมีปุ่ม “ซื้อ” หลายปุ่ม ให้เพิ่มตัวระบุ: “ซื้อ iPhone 15”, “ซื้อ iPhone 15 Pro”
การแปลภาษา — Content Description ต้องได้รับการแปลเป็นทุกภาษาที่แอปรองรับ ข้อผิดพลาดในการแปลคำอธิบายเป็นหนึ่งในสาเหตุทั่วไปของความล้มเหลวของ Accessibility Review ใน App Store
งานวิจัยของ Nielsen Norman Group, 2024 แสดงให้เห็นว่าความยาวคำอธิบายที่เหมาะสมที่สุดสำหรับโปรแกรมอ่านหน้าจอคือ 3–5 คำ (สูงสุด 50 ตัวอักษร) คำอธิบายที่ยาวกว่าจะลดความเร็วในการนำทางลง 30% เนื่องจากผู้ใช้ต้องรอให้การประกาศเสร็จสิ้นก่อนขั้นตอนถัดไป
ความซ้ำซ้อน — คำอธิบายซ้ำข้อความที่มองเห็น หากปุ่มมีข้อความ “ส่ง” อย่าตั้งค่า accessibilityHint = “ปุ่มส่ง” VoiceOver จะอ่านข้อความโดยอัตโนมัติ และ hint จะเพิ่มเสียงรบกวนที่ไม่จำเป็น
สับสนกับ Label — การใช้ contentDescription แทน label สำหรับปุ่มข้อความ ใน iOS accessibilityLabel ควรตรงกับข้อความของปุ่ม (หรือว่างหากข้อความแสดงอยู่แล้ว) และ hint ควรอธิบายการกระทำเท่านั้น ตาม Google Testing Blog, 2024 23% ของแอปที่ตรวจสอบใน Play Store มีคำอธิบายที่ซ้ำกัน
ละเลยความไดนามิก — คำอธิบายไม่อัปเดตเมื่อสถานะเปลี่ยนแปลง ตัวอย่างเช่น คำอธิบายของสวิตช์ “Wi-Fi” ยังคงเป็น “เปิด Wi-Fi” แม้หลังจากเปิดแล้ว วิธีการที่ถูกต้อง: เปลี่ยนคำอธิบายแบบไดนามิกเป็น “ปิด Wi-Fi” โดยการสังเกตสถานะ
หลังจากการอัปเดตการออกแบบ (การเปลี่ยนไอคอน การจัดเรียงองค์ประกอบใหม่) Content Description มักจะ หายไป สาเหตุ: นักออกแบบเปลี่ยนรูปภาพ และนักพัฒนาไม่ตรวจสอบคุณสมบัติการเข้าถึงของทรัพยากรใหม่ วิธีแก้ไข: ทำให้การตรวจสอบการเข้าถึงเป็นขั้นตอนบังคับในการตรวจสอบโค้ด — เพิ่มรายการตรวจสอบ: “Content Description อัปเดตแล้วหรือยัง?”
func testContentDescriptionExists() {
let app = XCUIApplication()
app.launch()
let image = app.images["chart-sales"]
XCTAssertNotNil(image.label)
XCTAssertGreaterThan(image.label.count, 0)
}
คำถามที่พบบ่อย
VoiceOver หรือ TalkBack จะประกาศเพียง “รูปภาพ” หรือ “ปุ่ม” โดยไม่ระบุวัตถุประสงค์ สิ่งนี้ละเมิด WCAG 1.1.1 และทำให้แอปไม่สามารถเข้าถึงได้สำหรับผู้ที่มีความบกพร่องทางการมองเห็น
ไม่ หากปุ่มมี ป้ายข้อความ VoiceOver จะอ่านโดยอัตโนมัติ สามารถเพิ่มคำอธิบาย (accessibilityHint) เพื่อชี้แจงผลลัพธ์ของการกด แต่ไม่จำเป็นต้องใช้ Label
ใน iOS ตั้งค่า isAccessibilityElement = false ใน Android ตั้งค่า contentDescription = "@null" โปรแกรมอ่านหน้าจอจะข้ามองค์ประกอบเหล่านี้โดยไม่ส่งเสียง
ใน iOS ใช้ NSLocalizedString สำหรับ accessibilityHint ใน Android — ทรัพยากรสตริงผ่าน @string/ การแปลคำอธิบายเป็นสิ่งจำเป็นสำหรับทุกภาษาที่รองรับ
เพิ่มการทดสอบ UI ที่ตรวจสอบการมีอยู่ของคำอธิบายสำหรับ ImageView ทั้งหมด ใน iOS — XCUIApplication ใน Android — AccessibilityCheckRule จาก Espresso สามารถเรียกใช้ Accessibility Scanner ใน CI ผ่านบรรทัดคำสั่ง
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม