สร้างระบบเมนูสำหรับผู้พิการ

เผยแพร่แล้ว: 2022-03-10
สรุปอย่างย่อ ↬ มีเมนูหลายประเภทในเว็บ การสร้างประสบการณ์ที่ครอบคลุมคือคำถามของการใช้รูปแบบเมนูที่เหมาะสมในสถานที่ที่เหมาะสม โดยมีมาร์กอัปและพฤติกรรมที่เหมาะสม

หมายเหตุบรรณาธิการ : บทความนี้เดิมปรากฏบนส่วนประกอบที่รวม หากคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับบทความเกี่ยวกับส่วนประกอบที่ครอบคลุมที่คล้ายกัน ให้ติดตาม @inclusicomps บน Twitter หรือสมัครรับฟีด RSS ด้วยการสนับสนุน inclusive-components.design บน Patreon คุณสามารถช่วยให้ฐานข้อมูลนี้เป็นฐานข้อมูลที่ครอบคลุมที่สุดของส่วนประกอบอินเทอร์เฟซที่มีประสิทธิภาพ

การจำแนกประเภทเป็นเรื่องยาก ยกตัวอย่างปู ปูเสฉวน ปูกระเบื้อง และปูเกือกม้า ไม่ใช่ปู ที่แท้จริง แต่นั่นไม่ได้หยุดเราใช้คำต่อท้าย "ปู" มันจะยิ่งสับสนมากขึ้นเรื่อยๆ เมื่อเวลาผ่านไป และด้วยกระบวนการที่เรียกว่าการ ก่อมะเร็ง ปูที่ไม่จริงจะมีวิวัฒนาการให้คล้ายกับปูจริงมากขึ้น นี่เป็นกรณีของปูราชาซึ่งเชื่อกันว่าเป็นปูเสฉวนในสมัยก่อน ลองนึกภาพขนาดของเปลือกหอย!

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

คำว่า "ดรอปดาวน์" เป็นตัวอย่างคลาสสิก "ดรอปดาวน์" มากมายในอินเทอร์เฟซ รวมถึงชุดของ <option> จากองค์ประกอบ <select> และรายการลิงก์ที่ JavaScript เปิดเผยซึ่งประกอบขึ้นเป็นเมนูย่อยการนำทาง ชื่อเดียวกัน; สิ่งที่แตกต่างกันมาก (บางคนเรียกว่า "การดึงลง" แน่นอน แต่อย่าพูดถึงเรื่องนี้)

ดรอปดาวน์ที่ประกอบเป็นชุดตัวเลือกมักเรียกว่า "เมนู" และฉันต้องการพูดถึงสิ่งเหล่านี้ที่นี่ เรากำลังคิดเมนูเด็ดอยู่ แต่ระหว่างทางก็มีเมนูที่ไม่ จริง มากมายให้พูดถึง

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

มาเริ่มกันที่ควิซ กล่องของลิงก์ห้อยลงมาจากแถบนำทางในภาพประกอบเป็นเมนูหรือไม่

แถบนำทางที่มีลิงค์ร้านค้า ด้านล่างซึ่งแขวนชุดลิงก์เพิ่มเติมอีกสามลิงก์ไปยังชุดสุนัข เตารีดวาฟเฟิล และลูกแก้ววิเศษตามลำดับ
แถบนำทางที่มีลิงค์ร้านค้า ด้านล่างซึ่งแขวนชุดลิงก์เพิ่มเติมอีกสามลิงก์ไปยังชุดสุนัข เตารีดวาฟเฟิล และลูกแก้ววิเศษตามลำดับ (ตัวอย่างขนาดใหญ่)

คำตอบคือ ไม่ใช่ ไม่ใช่เมนูจริง

เป็นข้อตกลงที่มีมาช้านานว่า schema การนำทางประกอบด้วยรายการลิงก์ อนุสัญญาที่ดำเนินมายาวนานเกือบเท่ากับว่าควรมีการจัดเตรียมการนำทางย่อยเป็นรายการลิงก์ที่ ซ้อนกัน หากฉันต้องลบ CSS สำหรับองค์ประกอบที่แสดงด้านบน ฉันควรเห็นสิ่งต่อไปนี้ ยกเว้นสีน้ำเงินและใน Times New Roman

พูดตามความหมายแล้ว รายการลิงก์ที่ซ้อนกันนั้นถูกต้องในบริบทนี้ ระบบนำทางคือ สารบัญ จริงๆ และนี่คือวิธีการจัดโครงสร้างสารบัญ สิ่งเดียวที่ทำให้เรานึกถึง "เมนู" จริงๆ ก็คือการจัดสไตล์ของรายการที่ซ้อนกันและวิธีการเปิดเผยเมื่อวางเมาส์เหนือหรือโฟกัส

นั่นคือสิ่งที่ผิดพลาดและเริ่มเพิ่มความหมายของ WAI-ARIA: aria-haspopup="true" , role="menu" , role="menuitem" เป็นต้น มีที่สำหรับสิ่งเหล่านี้ที่เราจะกล่าวถึง แต่ไม่ใช่ที่นี่ . นี่คือสาเหตุสองประการ:

  1. เมนู ARIA ไม่ได้กำหนดไว้สำหรับการนำทาง แต่สำหรับลักษณะการทำงานของแอปพลิเคชัน ลองนึกภาพระบบเมนูสำหรับแอปพลิเคชันเดสก์ท็อป
  2. ลิงก์ระดับบนสุดควรใช้ เป็นลิงก์ หมายความว่าลิงก์ไม่ทำงานเหมือนปุ่มเมนู

เกี่ยวกับ (2): เมื่อสำรวจพื้นที่การนำทางด้วยเมนูย่อย คาดว่าแต่ละเมนูย่อยจะปรากฏขึ้นเมื่อวางเมาส์เหนือหรือเน้นที่ลิงก์ "ระดับบนสุด" ("ร้านค้า" ในภาพประกอบ) ข้อมูลนี้จะแสดงเมนูย่อยและวางลิงก์ของตนเองในลำดับโฟกัส ด้วยความช่วยเหลือเล็กน้อยจาก JavaScript ในการจับโฟกัสและเบลอเหตุการณ์ เพื่อรักษาลักษณะที่ปรากฏของเมนูย่อยในขณะที่จำเป็น ผู้ที่ใช้แป้นพิมพ์ควรจะสามารถแท็บผ่านแต่ละลิงก์ของแต่ละระดับได้

ปุ่มเมนูที่ใช้คุณสมบัติ aria-haspopup="true" ไม่ทำงานเช่นนี้ พวกเขาจะเปิดใช้งานเมื่อ คลิก และไม่มีจุดประสงค์อื่นนอกจากการเปิดเผยเมนูลับ

ส่วนลด ebook bieten wir
ซ้าย: ปุ่มเมนูที่มีป้ายกำกับ 'เมนู' พร้อมไอคอนลูกศรชี้ลงและสถานะ aria-expanded = false ขวา: ปุ่มเมนูเดิมแต่เปิดเมนูอยู่ ปุ่มนี้อยู่ในสถานะ aria-expanded = true (ตัวอย่างขนาดใหญ่)

ตามภาพ ไม่ว่าเมนูนั้นจะเปิดหรือปิดอยู่ ควรสื่อสารกับ aria-expanded คุณควรเปลี่ยนสถานะนี้เมื่อคลิกเท่านั้น ไม่ใช่ที่โฟกัส ผู้ใช้มักไม่คาดหวังการเปลี่ยนแปลงอย่างชัดแจ้งในเหตุการณ์โฟกัส ในระบบนำทางของเรา สถานะไม่เปลี่ยนแปลงจริงๆ มันเป็นเพียงเคล็ดลับการจัดสไตล์ ตามพฤติกรรม เราสามารถ แท็บ ผ่านการนำทางราวกับว่าไม่มีการแสดง/ซ่อนกลอุบายดังกล่าวเกิดขึ้น

ปัญหาเกี่ยวกับเมนูย่อยการนำทาง

เมนูย่อยการนำทาง (หรือ "ดรอปดาวน์" สำหรับบางเมนู) ใช้งานได้ดีกับเมาส์หรือคีย์บอร์ด แต่ก็ไม่ได้ร้อนแรงนักเมื่อต้องสัมผัส เมื่อคุณกดลิงก์ "ร้านค้า" ระดับบนสุดในตัวอย่างของเราเป็นครั้งแรก แสดงว่าคุณกำลังบอกให้เปิดเมนูย่อยทั้งสองและไปตามลิงก์

มีสองวิธีแก้ปัญหาที่เป็นไปได้ที่นี่:

  1. ป้องกันพฤติกรรมเริ่มต้นของลิงก์ระดับบนสุด ( e.preventDefault() ) และสคริปต์ในความหมายและการทำงานของเมนู WAI-ARIA แบบเต็ม
  2. ตรวจสอบให้แน่ใจว่าหน้าปลายทางระดับบนสุดแต่ละหน้ามีสารบัญแทนเมนูย่อย

(1) ไม่เป็นที่น่าพอใจเพราะอย่างที่ฉันได้กล่าวไว้ก่อนหน้านี้ ความหมายและพฤติกรรมประเภทนี้ไม่คาดหวังในบริบทนี้ โดยที่ลิงก์เป็นตัวควบคุมหัวเรื่อง ผู้ใช้พลัสไม่สามารถนำทางไปยังหน้าระดับบนสุดได้อีกต่อไป หากมี

Sidenote: อุปกรณ์ใดบ้างที่เป็นอุปกรณ์ระบบสัมผัส

การคิดว่า "นี่ไม่ใช่วิธีแก้ปัญหาที่ดี แต่ฉันจะเพิ่มสำหรับอินเทอร์เฟซแบบสัมผัสเท่านั้น" เป็นเรื่องที่น่าดึงดูดใจ ปัญหาคือ จะตรวจจับได้อย่างไรว่าอุปกรณ์มีหน้าจอสัมผัสหรือไม่

คุณไม่ควรเทียบ "หน้าจอเล็ก" กับ "เปิดใช้งานระบบสัมผัส" อย่างแน่นอน เคยทำงานในสำนักงานเดียวกันกับคนทำระบบสัมผัสสำหรับพิพิธภัณฑ์ ฉันรับรองได้เลยว่าหน้าจอที่ใหญ่ที่สุดบางหน้าจอเป็นหน้าจอสัมผัส แล็ปท็อปคีย์บอร์ดคู่และอินพุตแบบสัมผัสก็มีจำนวนมากขึ้นเช่นกัน

ในทำนองเดียวกัน อุปกรณ์ขนาดเล็กจำนวนมากแต่ไม่ใช่ทั้งหมดเป็นอุปกรณ์ระบบสัมผัส ในการออกแบบที่ครอบคลุม คุณไม่สามารถที่จะตั้งสมมติฐานได้

ความละเอียด (2) มีความครอบคลุมและแข็งแกร่งมากขึ้น โดยมี "ทางเลือก" สำหรับผู้ใช้อินพุตทั้งหมด แต่คำพูดที่น่ากลัวเกี่ยวกับคำศัพท์ทางเลือกที่นี่ค่อนข้างรอบคอบเพราะฉันคิดว่าสารบัญในหน้าเป็นวิธีการที่ ดีกว่า ในการนำทาง

ทีมบริการดิจิทัลของรัฐบาลที่ได้รับรางวัลดูเหมือนจะเห็นด้วย คุณอาจเคยเห็นพวกเขาในวิกิพีเดีย

สารบัญ Gov.uk นั้นน้อยที่สุดโดยมียัติภังค์เป็นรูปแบบรายการ Wikipedia จัดเตรียมกล่องสีเทาที่มีขอบพร้อมรายการที่มีหมายเลข ทั้งสองเป็นเนื้อหาที่มีป้ายกำกับ
สารบัญ Gov.uk นั้นน้อยที่สุดโดยมียัติภังค์เป็นรูปแบบรายการ Wikipedia จัดเตรียมกล่องสีเทาที่มีขอบพร้อมรายการที่มีหมายเลข ทั้งสองเป็นเนื้อหาที่มีป้ายกำกับ

สารบัญ

สารบัญคือการนำทางสำหรับหน้าที่เกี่ยวข้องหรือส่วนของหน้า และควรมีความหมายคล้ายกับพื้นที่การนำทางของไซต์หลัก โดยใช้องค์ประกอบ <nav> รายการ และกลไกการติดป้ายกำกับกลุ่ม

 <nav aria-labelledby="sections-heading"> <h2>Products</h2> <ul> <li><a href="/products/dog-costumes">Dog costumes</a></li> <li><a href="/products/waffle-irons">Waffle irons</a></li> <li><a href="/products/magical-orbs">Magical orbs</a></li> </ul> </nav> <!-- each section, in order, here -->

หมายเหตุ

  • ในตัวอย่างนี้ เรากำลังจินตนาการว่าแต่ละส่วนเป็นหน้าของตัวเอง อย่างที่ควรจะเป็นในเมนูย่อยแบบเลื่อนลง
  • สิ่งสำคัญคือหน้า "ร้านค้า" แต่ละหน้ามีโครงสร้างเหมือนกัน โดยมีสารบัญ "ผลิตภัณฑ์" อยู่ในที่เดียวกัน ความสม่ำเสมอสนับสนุนความเข้าใจ
  • รายการจัดกลุ่มรายการและแจกแจงรายการในเอาต์พุตเทคโนโลยีอำนวยความสะดวก เช่น เสียงสังเคราะห์ของโปรแกรมอ่านหน้าจอ
  • <nav> มีป้ายกำกับซ้ำโดยส่วนหัวโดยใช้ aria-labelledby ซึ่งหมายความว่า "การนำทางผลิตภัณฑ์" จะประกาศในโปรแกรมอ่านหน้าจอส่วนใหญ่เมื่อเข้าสู่ภูมิภาคด้วย แท็บ นอกจากนี้ยังหมายความว่า "การนำทางผลิตภัณฑ์" จะถูกจัดรายการในอินเทอร์เฟซองค์ประกอบโปรแกรมอ่านหน้าจอ ซึ่งผู้ใช้สามารถนำทางไปยังภูมิภาคได้โดยตรง

ทั้งหมดในหน้าเดียว

หากคุณสามารถจัดส่วนทั้งหมดลงในหน้าเดียวได้โดยไม่ใช้เวลานานและยากต่อการเลื่อน ก็ยิ่งดีไปอีก เพียงเชื่อมโยงไปยังตัวระบุแฮชของแต่ละส่วน ตัวอย่างเช่น href="#waffle-irons" ควรชี้ไปที่ .

 <nav aria-labelledby="sections-heading"> <h2>Products</h2> <ul> <li><a href="#dog-costumes">Dog costumes</a></li> <li><a href="#waffle-irons">Waffle irons</a></li> <li><a href="#magical-orbs">Magical orbs</a></li> </ul> </nav> <!-- dog costumes section here --> <section tabindex="-1"> <h2>Waffle Irons</h2> </section> <!-- magical orbs section here -->

( หมายเหตุ: เบราว์เซอร์บางตัวไม่สามารถส่งโฟกัสไปยังแฟรกเมนต์ของหน้าที่เชื่อมโยงได้ การวาง tabindex="-1" บนแฟรกเมนต์เป้าหมายช่วยแก้ไขปัญหานี้ได้)

ในกรณีที่ไซต์มีเนื้อหาจำนวนมาก สถาปัตยกรรมข้อมูลที่สร้างขึ้นอย่างระมัดระวัง ซึ่งแสดงออกผ่านการใช้ "เมนู" ของสารบัญแบบเสรีนิยมมากกว่าระบบดรอปดาวน์ที่ไม่ปลอดภัยและเทอะทะ ไม่เพียงแต่จะทำให้การตอบสนองง่ายขึ้นเท่านั้น และต้องใช้โค้ดน้อยกว่าในการทำเช่นนั้น แต่ยังทำให้สิ่งต่างๆ ชัดเจนขึ้น โดยที่ระบบดรอปดาวน์จะซ่อนโครงสร้างไว้ สารบัญจะเปิดเผย

บางไซต์ รวมถึง gov.uk ของ Government Digital Service มีหน้าดัชนี (หรือ "หัวข้อ") ที่เป็น เพียง สารบัญ เป็นแนวคิดที่ทรงพลังที่ Hugo ตัวสร้างไซต์สแตติกยอดนิยมสร้างหน้าดังกล่าวโดยค่าเริ่มต้น

ไดอะแกรมแบบแผนภูมิต้นไม้ครอบครัวพร้อมหน้า Landing Page ของหัวข้อที่ด้านบน โดยมีหน่อแยกสองหน้า หน่อแต่ละหน้ามีหลายหน่อส่วนหน้า
ไดอะแกรมแบบแผนภูมิต้นไม้ครอบครัวพร้อมหน้า Landing Page ของหัวข้อที่ด้านบน โดยมีหน่อแยกสองหน้า หน่อแต่ละหน้าแต่ละหน่อมีหลายส่วนของหน้า (ตัวอย่างขนาดใหญ่)

สถาปัตยกรรมสารสนเทศเป็นส่วนสำคัญของการรวม ไซต์ที่มีการจัดระเบียบไม่ดีสามารถปฏิบัติตามข้อกำหนดทางเทคนิคได้ตามที่คุณต้องการ แต่จะทำให้ผู้ใช้จำนวนมากแปลกแยกออกไป โดยเฉพาะอย่างยิ่งผู้ที่มีความบกพร่องทางสติปัญญาหรือผู้ที่ถูกกดดันให้ใช้เวลา

ปุ่มเมนูนำทาง

ในขณะที่เรากำลังพูดถึงเมนูเกี่ยวกับการนำทางมารยาท ฉันจะไม่พูดถึงปุ่มเมนูการนำทาง คุณคงเคยเห็นสิ่งเหล่านี้เขียนแทนด้วยไอคอน "แฮมเบอร์เกอร์" หรือ "นาวิคอน" สามบรรทัด

แม้จะมีสถาปัตยกรรมข้อมูลแบบแยกย่อยและลิงก์การนำทางเพียงชั้นเดียว พื้นที่บนหน้าจอขนาดเล็กก็ยังมีราคาสูง การซ่อนการนำทางหลังปุ่มหมายความว่ามีพื้นที่มากขึ้นสำหรับเนื้อหาหลักในวิวพอร์ต

ปุ่มนำทางเป็นสิ่งที่ใกล้เคียงที่สุดที่เราเคยศึกษามาจนถึงปุ่มเมนู จริง เนื่องจากมีวัตถุประสงค์เพื่อสลับความพร้อมใช้งานของเมนูเมื่อคลิก จึงควร:

  1. ระบุตัวเองว่าเป็นปุ่ม ไม่ใช่ลิงก์
  2. ระบุสถานะขยายหรือยุบของเมนูที่เกี่ยวข้อง (ซึ่งในแง่ที่เข้มงวด เป็นเพียงรายการลิงก์)

การเพิ่มประสิทธิภาพแบบก้าวหน้า

แต่ขอไม่ไปข้างหน้าของตัวเอง เราควรคำนึงถึงการปรับปรุงแบบก้าวหน้าและพิจารณาว่าจะทำงานอย่างไรหากไม่มี JavaScript

ในเอกสาร HTML ที่ไม่ได้ปรับปรุง คุณทำอะไรกับปุ่มได้ไม่มาก (ยกเว้นปุ่มส่ง แต่นั่นไม่ได้เกี่ยวข้องอย่างใกล้ชิดกับสิ่งที่เราต้องการทำให้สำเร็จที่นี่) บางทีเราควรเริ่มต้นด้วยลิงก์ที่นำเราไปยังการนำทางแทน

 <a href="#navigation">navigation</a> <!-- some content here perhaps --> <nav> <ul> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> <li><a href="/shop">Shop</a></li> <li><a href="/content">Content</a></li> </ul> </nav>

ไม่มีประโยชน์มากมายในการมีลิงก์ เว้นแต่จะมีเนื้อหามากมายระหว่างลิงก์และการนำทาง เนื่องจากการนำทางไซต์ควรปรากฏใกล้กับด้านบนสุดของลำดับต้นทางเกือบทุกครั้ง จึงไม่มีความจำเป็น ดังนั้น จริงๆ แล้ว เมนูการนำทางในกรณีที่ไม่มี JavaScript ควรจะเป็น... การนำทางบางส่วน

 <nav> <ul> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> <li><a href="/shop">Shop</a></li> <li><a href="/content">Content</a></li> </ul> </nav>

คุณปรับปรุงสิ่งนี้โดยเพิ่มปุ่ม ในสถานะเริ่มต้น และซ่อนการนำทาง (โดยใช้แอตทริบิวต์ที่ hidden ):

 <nav> <button aria-expanded="false">Menu</button> <ul hidden> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> <li><a href="/shop">Shop</a></li> <li><a href="/contact">Contact</a></li> </ul> </nav>

เบราว์เซอร์รุ่นเก่าบางตัว — คุณรู้ว่าเบราว์เซอร์ใด — ไม่รองรับ hidden ดังนั้นอย่าลืมใส่สิ่งต่อไปนี้ใน CSS ของคุณ แก้ไขปัญหาได้เนื่องจาก display: none มีผลเช่นเดียวกันกับการซ่อนเมนูจากเทคโนโลยีช่วยเหลือและลบลิงก์ออกจากลำดับโฟกัส

 [hidden] { display: none; }

แน่นอนว่าการพยายามอย่างเต็มที่เพื่อสนับสนุนซอฟต์แวร์รุ่นเก่าคือการออกแบบที่ครอบคลุม บางคนไม่สามารถหรือไม่เต็มใจที่จะอัพเกรด

ตำแหน่ง

จุดที่หลายคนผิดพลาดคือการวางปุ่มไว้ นอก ภูมิภาค ซึ่งหมายความว่าผู้ใช้โปรแกรมอ่านหน้าจอที่ย้ายไปที่ <nav> โดยใช้ทางลัดจะพบว่าว่างเปล่า ซึ่งไม่เป็นประโยชน์มากนัก ด้วยรายการที่ซ่อนอยู่จากโปรแกรมอ่านหน้าจอ พวกเขาจะพบสิ่งนี้:

 <nav> </nav>

ต่อไปนี้คือวิธีที่เราอาจสลับสถานะ:

 var navButton = document.querySelector('nav button'); navButton.addEventListener('click', function() { let expanded = this.getAttribute('aria-expanded') === 'true' || false; this.setAttribute('aria-expanded', !expanded); let menu = this.nextElementSibling; menu.hidden = !menu.hidden; });

aria-controls

ตามที่ฉันเขียนใน Aria-controls Is Poop แอตทริบิวต์ aria-controls ซึ่งมีจุดมุ่งหมายเพื่อช่วยให้ผู้ใช้โปรแกรมอ่านหน้าจอนำทางจากองค์ประกอบการควบคุมไปยังองค์ประกอบที่ควบคุม ได้รับการสนับสนุนในโปรแกรมอ่านหน้าจอ JAWS เท่านั้น ดังนั้นคุณจึงไม่สามารถพึ่งพาได้

หากไม่มีวิธีการที่ดีในการชี้นำผู้ใช้ระหว่างองค์ประกอบ คุณควรตรวจสอบให้แน่ใจว่าข้อใดข้อหนึ่งต่อไปนี้เป็นจริง:

  1. ลิงก์แรกของรายการที่ขยายจะอยู่ถัดไปในลำดับโฟกัสหลังปุ่ม (ดังในตัวอย่างโค้ดก่อนหน้า)
  2. ลิงก์แรกเน้นโดยทางโปรแกรมเมื่อเปิดเผยรายการ

ในกรณีนี้ ผมขอแนะนำ (1) มันง่ายกว่ามากเพราะคุณไม่ต้องกังวลเกี่ยวกับการย้ายโฟกัสกลับไปที่ปุ่มและเหตุการณ์ที่ต้องทำ นอกจากนี้ ขณะนี้ยังไม่มีสิ่งใดที่จะเตือนผู้ใช้ว่าโฟกัสของพวกเขาจะถูกย้ายไปยังที่อื่น ในเมนูจริงเราจะพูดถึงในไม่ช้า นี่คืองานของ aria-haspopup="true"

การใช้ aria-controls ไม่ได้ทำอันตรายอะไรมาก ยกเว้นแต่จะทำให้การอ่านข้อมูลในโปรแกรมอ่านหน้าจอมีความละเอียดมากขึ้น อย่างไรก็ตาม ผู้ใช้ JAWS บางคนอาจคาดหวังไว้ นี่คือวิธีนำไปใช้โดยใช้ id ของรายการเป็นรหัส:

 <nav> <button aria-expanded="false" aria-controls="menu-list">Menu</button> <ul hidden> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> <li><a href="/shop">Shop</a></li> <li><a href="/contact">Contact</a></li> </ul> </nav>

บทบาทของเมนูและรายการเมนู

เมนู จริง (ในความหมายของ WAI-ARIA) ควรระบุตัวเองโดยใช้บทบาท menu (สำหรับคอนเทนเนอร์) และโดยทั่วไปแล้ว menuitem ของรายการเมนู (อาจใช้บทบาทย่อยอื่นๆ) บทบาทผู้ปกครองและเด็กเหล่านี้ทำงานร่วมกันเพื่อให้ข้อมูลแก่เทคโนโลยีอำนวยความสะดวก ต่อไปนี้คือวิธีการเพิ่มรายการเพื่อให้มีความหมายของเมนู:

 <ul role="menu"> <li role="menuitem">Item 1</li> <li role="menuitem">Item 2</li> <li role="menuitem">Item 3</li> </ul>

เนื่องจากเมนูการนำทางของเราเริ่มมีลักษณะเหมือนเมนู "จริง" จึงไม่ควรปรากฏ

คำตอบสั้น ๆ คือ: ไม่ คำตอบที่ยาวเหยียดคือ: ไม่ เนื่องจากรายการของเรามีลิงก์และองค์ประกอบ menuitem ไม่ได้มีไว้สำหรับลูกหลานแบบโต้ตอบ นั่น คือ การควบคุมในเมนู

แน่นอน เราสามารถระงับความหมายของรายการของ <li> โดยใช้ role="presentation" หรือ role="none" (ซึ่งเทียบเท่ากัน) และวางบทบาท menuitem ในแต่ละลิงก์ อย่างไรก็ตาม สิ่งนี้จะระงับบทบาทลิงก์โดยนัย กล่าวอีกนัยหนึ่ง ตัวอย่างต่อไปนี้จะประกาศเป็น "หน้าแรก รายการเมนู" ไม่ใช่ "หน้าแรก ลิงก์" หรือ "หน้าแรก รายการเมนู ลิงก์" บทบาท ARIA จะแทนที่บทบาท HTML เพียงอย่างเดียว

 <!-- will be read as "Home, menu item" --> <li role="presentation"> <a href="/" role="menuitem">Home</a> </li>

เราต้องการให้ผู้ใช้รู้ว่าพวกเขากำลังใช้ลิงก์และสามารถคาดหวังพฤติกรรมของลิงก์ได้ ดังนั้นนี่จึงไม่ใช่เรื่องดี อย่างที่ฉันพูด เมนูจริงมีไว้สำหรับลักษณะการทำงานของแอปพลิเคชัน (ที่ขับเคลื่อนด้วย JavaScript)

สิ่งที่เราเหลือคือองค์ประกอบไฮบริดชนิดหนึ่ง ซึ่งไม่ใช่เมนูจริง แต่อย่างน้อยก็บอกผู้ใช้ว่ารายการลิงก์เปิดอยู่หรือไม่ ขอบคุณสถานะ aria-expanded นี่เป็นรูปแบบที่น่าพอใจอย่างยิ่งสำหรับเมนูการนำทาง

Sidenote: <select> องค์ประกอบ

หากคุณเคยมีส่วนร่วมในการออกแบบที่ตอบสนองได้ตั้งแต่ต้น คุณอาจจำรูปแบบที่การนำทางถูกย่อให้เป็นองค์ประกอบ <select> สำหรับวิวพอร์ตแบบแคบ

เครื่องโทรศัพท์ที่มีองค์ประกอบที่เลือกแสดง "บ้าน" ที่เลือกไว้ที่ด้านบนของวิวพอร์ต
โทรศัพท์มือถือที่มีองค์ประกอบที่เลือกแสดง "บ้าน" ที่เลือกไว้ที่ด้านบนของวิวพอร์ต

เช่นเดียวกับปุ่มสลับตามช่องทำเครื่องหมายที่เราได้พูดคุยกัน การใช้องค์ประกอบดั้งเดิมที่ทำงานค่อนข้างตามที่ตั้งใจไว้โดยไม่ต้องเขียนสคริปต์เพิ่มเติมเป็นทางเลือกที่ดีสำหรับประสิทธิภาพและ — โดยเฉพาะบนอุปกรณ์เคลื่อนที่ — ประสิทธิภาพ และองค์ประกอบ <select> เป็น เมนูที่มีลักษณะแปลก ๆ โดยมีความหมายคล้ายกับเมนูที่เรียกปุ่มซึ่งเราจะสร้างขึ้นในไม่ช้า

อย่างไรก็ตาม เช่นเดียวกับปุ่มสลับช่องทำเครื่องหมาย เรากำลังใช้องค์ประกอบที่เกี่ยวข้องกับการป้อนข้อมูล ไม่ใช่แค่การเลือก ซึ่งอาจก่อให้เกิดความสับสนสำหรับผู้ใช้จำนวนมาก โดยเฉพาะอย่างยิ่งเนื่องจากรูปแบบนี้ใช้ JavaScript เพื่อทำให้ <option> ที่เลือกทำงานเหมือนลิงก์ การเปลี่ยนแปลงบริบทที่ไม่คาดคิดซึ่งทำให้เกิดนี้ถือเป็นความล้มเหลวตามเกณฑ์ 3.2.2 On Input (ระดับ A) ของ WCAG

เมนูทรู

ตอนนี้เราได้หารือเกี่ยวกับเมนูเท็จและกึ่งเมนูแล้ว ถึงเวลาสร้างเมนู ที่แท้จริง แล้ว โดยเปิดและปิดด้วยปุ่มเมนูจริง จากนี้ไปในฉันจะอ้างถึงปุ่มและเมนูร่วมกันเป็นเพียงแค่ "ปุ่มเมนู"

แต่ปุ่มเมนูของเราจะเป็นจริงในด้านใดบ้าง? มันจะเป็นองค์ประกอบเมนูที่มีไว้สำหรับเลือกตัวเลือกในแอปพลิเคชันหัวเรื่อง ซึ่งใช้ความหมายที่คาดหวังและพฤติกรรมที่เกี่ยวข้องทั้งหมดเพื่อพิจารณาแบบธรรมดาสำหรับเครื่องมือดังกล่าว

ดังที่ได้กล่าวไปแล้ว ข้อตกลงเหล่านี้มาจากการออกแบบแอปพลิเคชันเดสก์ท็อป การระบุแหล่งที่มาของ ARIA และการจัดการโฟกัสที่ควบคุมด้วย JavaScript เป็นสิ่งจำเป็นเพื่อเลียนแบบทั้งหมด จุดประสงค์ส่วนหนึ่งของ ARIA คือการช่วยให้นักพัฒนาเว็บสร้างประสบการณ์เว็บที่สมบูรณ์โดยไม่ทำลายข้อตกลงการใช้งานที่ปลอมแปลงขึ้นในโลกดั้งเดิม

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

 <button aria-haspopup="true" aria-expanded="false"> Difficulty <span aria-hidden="true">&#x25be;</span> </button> <div role="menu"> <button role="menuitem">Easy</button> <button role="menuitem">Medium</button> <button role="menuitem">Incredibly Hard</button> </div>

หมายเหตุ

  • คุณสมบัติ aria-haspopup บ่งชี้ว่าปุ่มนี้สร้างเมนู มันทำหน้าที่เตือนว่าเมื่อกดแล้วผู้ใช้จะถูกย้ายไปที่เมนู "ป๊อปอัป" (เราจะกล่าวถึงพฤติกรรมการโฟกัสในไม่ช้า) ค่าของมันไม่เปลี่ยนแปลง — ยังคงเป็น true ตลอดเวลา
  • <span> ภายในปุ่มมีจุดยูนิโค้ดสำหรับสามเหลี่ยมเล็กชี้ลงสีดำ แบบแผนนี้บ่งชี้ด้วยสายตาว่า aria-haspopup ทำอะไรโดยไม่มองเห็นได้ — การกดปุ่มจะแสดงบางสิ่งที่อยู่ด้านล่าง การระบุแหล่งที่มา aria-hidden="true" ป้องกันไม่ให้โปรแกรมอ่านหน้าจอประกาศ "สามเหลี่ยมชี้ลง" หรือที่คล้ายกัน ขอบคุณ aria-haspopup มันไม่จำเป็นในบริบทที่ไม่ใช่ภาพ
  • คุณสมบัติ aria-haspopup เสริมด้วย aria-expanded สิ่งนี้จะบอกผู้ใช้ว่าขณะนี้เมนูอยู่ในสถานะเปิด (ขยาย) หรือปิด (ยุบ) โดยการสลับระหว่างค่า true และ false
  • เมนูนี้ใช้บทบาท menu (ชื่อที่เหมาะเจาะ) มันใช้ทายาทที่มีบทบาท menuitem พวกเขาไม่จำเป็นต้องเป็นลูกโดยตรงขององค์ประกอบ menu แต่ในกรณีนี้ - เพื่อความเรียบง่าย

แป้นพิมพ์และพฤติกรรมการโฟกัส

เมื่อพูดถึงการทำให้แป้นพิมพ์ควบคุมแบบโต้ตอบสามารถเข้าถึงได้ สิ่งที่ดีที่สุดที่คุณสามารถทำได้คือการใช้องค์ประกอบที่เหมาะสม เนื่องจากเราใช้องค์ประกอบ <button> ที่นี่ เราจึงมั่นใจได้ว่าเหตุการณ์การคลิกจะเริ่มขึ้นเมื่อกดแป้น Enter และ Space ตามที่ระบุไว้ในอินเทอร์เฟซ HTMLButtonElement นอกจากนี้ยังหมายความว่าเราสามารถปิดการใช้งานรายการเมนูโดยใช้คุณสมบัติ disabled การใช้งานที่เกี่ยวข้องกับปุ่ม

การโต้ตอบกับแป้นพิมพ์ของปุ่มเมนูยังมีอะไรอีกมากมาย ต่อไปนี้คือข้อมูลสรุปของการโฟกัสและการทำงานของแป้นพิมพ์ทั้งหมดที่เราจะนำไปใช้ โดยยึดตามแนวทางปฏิบัติการเขียน WAI-ARIA 1.1:

ป้อน , เว้น วรรค หรือ บนปุ่มเมนู เปิดเมนู
ในรายการเมนู ย้ายโฟกัสไปที่รายการเมนูถัดไป หรือรายการเมนูแรกหากคุณอยู่ที่รายการสุดท้าย
ในรายการเมนู ย้ายโฟกัสไปที่รายการเมนูก่อนหน้า หรือรายการเมนูสุดท้ายหากคุณอยู่ที่รายการแรก
บนปุ่มเมนู ปิดเมนูหากเปิดอยู่
Esc ในรายการเมนู ปิดเมนูและโฟกัสที่ปุ่มเมนู

ข้อดีของการย้ายโฟกัสระหว่างรายการเมนูโดยใช้ปุ่มลูกศรคือ Tab จะถูกสงวนไว้สำหรับการย้ายออกจากเมนู ในทางปฏิบัติ หมายความว่าผู้ใช้ไม่ต้องเลื่อนดูทุกรายการเมนูเพื่อออกจากเมนู — การปรับปรุงอย่างมากสำหรับการใช้งาน โดยเฉพาะอย่างยิ่งเมื่อมีรายการเมนูมากมาย

การใช้งาน tabindex="-1" ทำให้รายการเมนูไม่สามารถโฟกัสได้ด้วย Tab แต่ยังคงความสามารถในการโฟกัสองค์ประกอบโดยทางโปรแกรม เมื่อจับภาพการกดปุ่มบนปุ่มลูกศร

 <button aria-haspopup="true" aria-expanded="false"> Difficulty <span aria-hidden="true">&#x25be;</span> </button> <div role="menu"> <button role="menuitem" tabindex="-1">Easy</button> <button role="menuitem" tabindex="-1">Medium</button> <button role="menuitem" tabindex="-1">Incredibly Hard</button> </div>

วิธีการเปิด

เป็นส่วนหนึ่งของการออกแบบเสียง API เราสามารถสร้างวิธีการในการจัดการเหตุการณ์ต่างๆ

ตัวอย่างเช่น วิธี open จำเป็นต้องเปลี่ยนค่า aria-expanded เป็น "จริง" เปลี่ยนคุณสมบัติที่ซ่อนอยู่ของเมนูเป็น false และเน้น menuitem แรกในเมนูที่ไม่ถูกปิดใช้งาน:

 MenuButton.prototype.open = function () { this.button.setAttribute('aria-expanded', true); this.menu.hidden = false; this.menu.querySelector(':not(\[disabled])').focus(); return this; }

เราสามารถใช้วิธีนี้โดยที่ผู้ใช้กดปุ่มลงบนอินสแตนซ์ปุ่มเมนูที่เน้น:

 this.button.addEventListener('keydown', function (e) { if (e.keyCode === 40) { this.open(); } }.bind(this));

นอกจากนี้ นักพัฒนาที่ใช้สคริปต์นี้จะสามารถเปิดเมนูโดยทางโปรแกรมได้แล้ว:

 exampleMenuButton = new MenuButton(document.querySelector('\[aria-haspopup]')); exampleMenuButton.open();

Sidenote: ช่องทำเครื่องหมาย hack

มากที่สุดเท่าที่เป็นไปได้ เป็นการดีกว่าที่จะไม่ใช้ JavaScript เว้นแต่ว่าคุณต้องการ การนำเทคโนโลยีที่สามมาใช้กับ HTML และ CSS จำเป็นต้องเพิ่มความซับซ้อนและความเปราะบางของระบบ อย่างไรก็ตาม ไม่ใช่ทุกองค์ประกอบที่สามารถสร้างขึ้นได้อย่างน่าพอใจโดยไม่ต้องใช้ JavaScript ในการผสมผสาน

ในกรณีของปุ่มเมนู ความกระตือรือร้นในการทำให้ปุ่มเหล่านี้ "ทำงานได้โดยไม่ต้องใช้ JavaScript" ทำให้เกิดสิ่งที่เรียกว่าการแฮ็กช่องทำเครื่องหมาย นี่คือตำแหน่งที่ใช้สถานะที่เลือก (หรือไม่ได้เลือก) ของช่องทำเครื่องหมายที่ซ่อนอยู่เพื่อสลับการมองเห็นองค์ประกอบเมนูโดยใช้ CSS

 /* menu closed */ [type="checkbox"] + [role="menu"] { display: none; } /* menu open */ [type="checkbox"]:checked + [role="menu"] { display: block; }

สำหรับผู้ใช้โปรแกรมอ่านหน้าจอ บทบาทช่องทำเครื่องหมายและสถานะที่เลือกนั้นไร้สาระในบริบทนี้ สิ่งนี้สามารถเอาชนะได้บางส่วนโดยการเพิ่ม role="button" ลงในช่องทำเครื่องหมาย

 <input type="checkbox" role="button" aria-haspopup="true">

น่าเสียดายที่สิ่งนี้ยับยั้งการสื่อสารสถานะที่ตรวจสอบโดยนัย ทำให้เราขาดการตอบกลับสถานะที่ปราศจาก JavaScript (แย่แม้ว่าจะถูก "ตรวจสอบ" ในบริบทนี้)

แต่ สามารถ ปลอมแปลง aria-expanded ได้ เราเพียงแค่ต้องจัดหาฉลากของเราด้วยช่วงสองช่วงด้านล่าง

 <input type="checkbox" role="button" aria-haspopup="true" class="vh"> <label for="toggle" data-opens-menu> Difficulty <span class="vh expanded-text">expanded&lt;/span> <span class="vh collapsed-text">collapsed</span> <span aria-hidden="true">&#x25be;</span> </label>

สิ่งเหล่านี้ถูกซ่อนด้วยสายตาโดยใช้คลาส visually-hidden แต่ — ขึ้นอยู่กับสถานะที่เราอยู่ใน — มีเพียงคนเดียวเท่านั้นที่ถูกซ่อนสำหรับโปรแกรมอ่านหน้าจอเช่นกัน นั่นคือ มีเพียงรายการเดียวเท่านั้นที่มี display: none และสิ่งนี้ถูกกำหนดโดยสถานะที่ตรวจสอบที่ยังหลงเหลืออยู่ (แต่ไม่ได้สื่อสาร):

 /* class to hide spans visually */ .vh { position: absolute !important; clip: rect(1px, 1px, 1px, 1px); padding: 0 !important; border: 0 !important; height: 1px !important; width: 1px !important; overflow: hidden; } /* reveal the correct state wording to screen readers based on state */ [type="checkbox"]:checked + label .expanded-text { display: inline; } [type="checkbox"]:checked + label .collapsed-text { display: none; } [type="checkbox"]:not(:checked) + label .expanded-text { display: none; } [type="checkbox"]:not(:checked) + label .collapsed-text { display: inline; }

นี่เป็นสิ่งที่ฉลาดและทั้งหมด แต่ปุ่มเมนูของเรายังไม่สมบูรณ์เนื่องจากพฤติกรรมการโฟกัสที่คาดหวังที่เราได้พูดคุยกันนั้นไม่สามารถนำไปใช้ได้หากไม่มี JavaScript

ลักษณะการทำงานเหล่านี้เป็นแบบทั่วไปและคาดว่าจะทำให้ปุ่มใช้งานได้มากขึ้น อย่างไรก็ตาม หากคุณต้องการใช้ปุ่มเมนูโดยไม่มี JavaScript จริงๆ สิ่งนี้จะใกล้เคียงที่สุดเท่าที่จะทำได้ เมื่อพิจารณาถึงปุ่มเมนูการนำทางแบบย่อที่ฉันกล่าวถึงก่อนหน้านี้มีเนื้อหาเมนูที่ ไม่ ขึ้นกับ JavaScript (เช่น ลิงก์) วิธีนี้อาจเป็นตัวเลือกที่เหมาะสม

เพื่อความสนุก นี่คือ codePen ที่ใช้ปุ่มเมนูการนำทางแบบไม่มี JavaScript

ดูตัวอย่างปุ่มเมนูการนำทางด้วยปากกา ไม่มี JS โดย Heydon (@heydon) บน CodePen

( หมายเหตุ: เฉพาะ Space เท่านั้นที่เปิดเมนูได้)

งาน “เลือก”

การดำเนินการบางวิธีควรปล่อยเหตุการณ์เพื่อให้เราสามารถตั้งค่าผู้ฟังได้ ตัวอย่างเช่น เราสามารถปล่อยเหตุการณ์ select เมื่อผู้ใช้คลิก choose รายการเมนู เราสามารถตั้งค่านี้ได้โดยใช้ CustomEvent ซึ่งช่วยให้เราส่งอาร์กิวเมนต์ไปยังคุณสมบัติ detail ของเหตุการณ์ได้ ในกรณีนี้ อาร์กิวเมนต์ (“ตัวเลือก”) จะเป็นโหนด DOM ของรายการเมนูที่เลือก

 MenuButton.prototype.choose = function (choice) { // Define the 'choose' event var chooseEvent = new CustomEvent('choose', { detail: { choice: choice } }); // Dispatch the event this.button.dispatchEvent(chooseEvent); return this; }

มีหลายสิ่งที่เราสามารถทำได้ด้วยกลไกนี้ บางทีเราอาจตั้งค่าภูมิภาคแบบสดด้วย id ของ menuFeedback :

 <div role="alert"></div>

ตอนนี้ เราสามารถตั้งค่าผู้ฟังและเติมข้อมูลในพื้นที่สดด้วยข้อมูลลับภายในเหตุการณ์:

 exampleMenuButton.addEventListener('choose', function (e) { // Get the node's text content (label) var choiceLabel = e.details.choice.textContent; // Get the live region node var liveRegion = document.getElementById('menuFeedback'); // Populate the live region liveRegion.textContent = 'Your difficulty level is ${choiceLabel}'; });
เมื่อผู้ใช้เลือกตัวเลือก เมนูจะปิดและโฟกัสจะกลับไปที่ปุ่มเมนู เป็นสิ่งสำคัญที่ผู้ใช้จะกลับไปที่องค์ประกอบที่เรียกหลังจากปิดเมนู
เมื่อผู้ใช้เลือกตัวเลือก เมนูจะปิดและโฟกัสจะกลับไปที่ปุ่มเมนู เป็นสิ่งสำคัญที่ผู้ใช้จะกลับไปที่องค์ประกอบที่เรียกหลังจากปิดเมนู (ตัวอย่างขนาดใหญ่)

เมื่อเลือกรายการเมนูแล้ว ผู้ใช้โปรแกรมอ่านหน้าจอจะได้ยินว่า “คุณเลือก [ป้ายกำกับรายการเมนู]” ภูมิภาคที่ใช้งานจริง (กำหนดที่นี่ด้วยการแสดงที่มาของ role=“alert” ) ประกาศเนื้อหาในโปรแกรมอ่านหน้าจอทุกครั้งที่เนื้อหาเปลี่ยนแปลง ภูมิภาคที่ใช้งานจริงไม่ได้บังคับ แต่เป็นตัวอย่างของสิ่งที่อาจเกิดขึ้นในอินเทอร์เฟซเพื่อตอบสนองต่อผู้ใช้ที่ทำการเลือกเมนู

ทางเลือกที่คงอยู่

รายการเมนูบางรายการไม่ได้มีไว้สำหรับการเลือกการตั้งค่าแบบถาวร หลายคนทำเหมือนปุ่มมาตรฐานที่ทำให้บางอย่างในอินเทอร์เฟซเกิดขึ้นเมื่อกด อย่างไรก็ตาม ในกรณีของปุ่มเมนูความยาก เราต้องการระบุว่าการตั้งค่าใดคือการตั้งค่าความยากในปัจจุบัน — อันที่เลือกไว้สุดท้าย

แอ็ตทริบิวต์ aria-checked="true" ใช้ได้กับรายการที่แทนที่ menuitem มีบทบาท menuitemradio มาร์กอัปที่ปรับปรุงแล้วโดยเลือกรายการที่สอง ( set ) มีลักษณะดังนี้:

 <button aria-haspopup="true" aria-expanded="false"> Difficulty <span aria-hidden="true">&#x25be;</span> </button> <div role="menu"> <button role="menuitemradio" tabindex="-1">Easy</button> <button role="menuitemradio" aria-checked="true" tabindex="-1">Medium</button> <button role="menuitemradio" tabindex="-1">Incredibly Hard</button> </div>

เมนูเนทีฟบนหลายแพลตฟอร์มระบุรายการที่เลือกโดยใช้เครื่องหมายถูก เราสามารถทำได้โดยไม่มีปัญหาโดยใช้ CSS เพิ่มเติมเล็กน้อย:

 [role="menuitem"] [aria-checked="true"]::before { content: '\2713\0020'; }

ขณะสำรวจเมนูโดยที่โปรแกรมอ่านหน้าจอทำงาน การเน้นรายการที่เลือกนี้จะแจ้งประกาศ เช่น “เครื่องหมายถูก รายการเมนูขนาดกลาง ตรวจสอบแล้ว”

ลักษณะการทำงานในการเปิดเมนูด้วยเมนูที่เลือก menuitemradio แตกต่างกันเล็กน้อย แทนที่จะโฟกัสรายการแรก (เปิดใช้งาน) ในเมนู รายการที่ เลือก จะถูกโฟกัสแทน

ปุ่มเมนูเริ่มต้นด้วยการเปิดเมนู เมื่อเปิดการตั้งค่าความยากที่สอง (ปานกลาง) จะเน้น โดยนำหน้าด้วยเครื่องหมายถูกตามการมีอยู่ของแอตทริบิวต์ที่ตรวจสอบโดย aria
ปุ่มเมนูเริ่มต้นด้วยการเปิดเมนู เมื่อเปิดการตั้งค่าความยากที่สอง (ปานกลาง) จะเน้น โดยนำหน้าด้วยเครื่องหมายถูกตามการมีอยู่ของแอตทริบิวต์ที่ตรวจสอบโดย aria (ตัวอย่างขนาดใหญ่)

ประโยชน์ของพฤติกรรมนี้คืออะไร? ผู้ใช้ (ผู้ใช้ทุกคน) จะได้รับการเตือนถึงตัวเลือกที่เลือกไว้ก่อนหน้านี้ ในเมนูที่มีตัวเลือกที่เพิ่มขึ้นมากมาย (เช่น ชุดระดับการซูม) ผู้ที่ใช้แป้นพิมพ์จะอยู่ในตำแหน่งที่เหมาะสมที่สุดเพื่อทำการปรับ

การใช้ปุ่มเมนูกับโปรแกรมอ่านหน้าจอ

ในวิดีโอนี้ ฉันจะแสดงให้คุณเห็นว่าการใช้ปุ่มเมนูกับโปรแกรมอ่านหน้าจอ Voiceover และ Chrome เป็นอย่างไร ตัวอย่างใช้รายการที่มี menuitemradio aria-checked และพฤติกรรมการโฟกัสที่กล่าวถึง ประสบการณ์ที่คล้ายคลึงกันสามารถคาดหวังได้ในทุกช่วงของซอฟต์แวร์โปรแกรมอ่านหน้าจอยอดนิยม

ปุ่มเมนูรวมบน Github

ฉันกับคิตตี้ จิราเดลได้ทำงานร่วมกันเพื่อสร้างส่วนประกอบปุ่มเมนูด้วยคุณสมบัติ API ที่ฉันอธิบาย และอื่นๆ อีกมากมาย คุณมี Hugo ที่ต้องขอบคุณสำหรับฟีเจอร์เหล่านี้มากมาย เนื่องจากพวกมันทำงานบน a11y-dialog ซึ่งเป็นกล่องโต้ตอบโมดอลที่เข้าถึงได้ มีอยู่ใน Github และ NPM

 npm i inclusive-menu-button --save

นอกจากนี้ Kitty ได้สร้างเวอร์ชัน React สำหรับการเลือกของคุณ

รายการตรวจสอบ

  • อย่าใช้ความหมายของเมนู ARIA ในระบบเมนูนำทาง
  • บนไซต์ที่มีเนื้อหาหนัก อย่าซ่อนโครงสร้างในเมนูการนำทางแบบดรอปดาวน์ที่ซ้อนอยู่
  • ใช้ aria-expanded เพื่อระบุสถานะเปิด/ปิดของเมนูการนำทางที่เปิดใช้งานปุ่ม
  • ตรวจสอบให้แน่ใจว่าเมนูการนำทางดังกล่าวอยู่ในลำดับโฟกัสถัดจากปุ่มที่เปิด/ปิด
  • อย่าเสียสละความสามารถในการใช้งานในการแสวงหาโซลูชันที่ปราศจาก JavaScript มันเป็นโต๊ะเครื่องแป้ง