แก้ไขลำดับ DOM ด้วย Tabindex

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

การรองรับเบราว์เซอร์

  • 1
  • 12
  • 1.5
  • อย่างน้อย 4

แหล่งที่มา

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

tabindex="0": แทรกองค์ประกอบในลำดับแท็บตามปกติ โฟกัสองค์ประกอบได้โดยกด Tab และโฟกัสองค์ประกอบได้โดยเรียกใช้เมธอด focus()

tabindex="-1": นำองค์ประกอบออกจากลำดับแท็บตามปกติ แต่จะยังคงโฟกัสองค์ประกอบได้โดยเรียกใช้เมธอด focus()

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

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

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

จัดการโฟกัสที่ระดับหน้าเว็บ

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

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

จัดการโฟกัสในคอมโพเนนต์

ในบางกรณี คุณต้องจัดการโฟกัสที่ระดับการควบคุมด้วย เช่น ด้วยคอมโพเนนต์ที่กำหนดเอง

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

การรู้ลักษณะการทำงานของแป้นพิมพ์ที่อาจเป็นเรื่องยาก คู่มือ Accessible Rich Internet Applications (ARIA) Authoring Practices แสดงประเภทของคอมโพเนนต์และประเภทการทำงานของแป้นพิมพ์ที่รองรับ

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

<radio-group>
    <radio-button>Water</radio-button>
    <radio-button>Coffee</radio-button>
    <radio-button>Tea</radio-button>
    <radio-button>Cola</radio-button>
    <radio-button>Ginger Ale</radio-button>
</radio-group>

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

ลักษณะการทํางานทั่วไปอย่างหนึ่งของแป้นพิมพ์ที่ควรรองรับคือแป้นลูกศรขึ้น/ลง/ซ้าย/ขวา ในการเพิ่มพฤติกรรมนี้ในคอมโพเนนต์ใหม่ เราใช้เทคนิคที่เรียกว่า rovingtabindex

Roving Tabindex ทำงานโดยการตั้งค่า tabindex เป็น -1 สำหรับผู้เผยแพร่โฆษณาย่อยทั้งหมด ยกเว้นรายการที่ใช้งานอยู่ในขณะนี้

<radio-group>
  <radio-button tabindex="0">Water</radio-button>
  <radio-button tabindex="-1">Coffee</radio-button>
  <radio-button tabindex="-1">Tea</radio-button>
  <radio-button tabindex="-1">Cola</radio-button>
  <radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>

คอมโพเนนต์จะใช้ Listener เหตุการณ์ในแป้นพิมพ์เพื่อกำหนดว่าผู้ใช้จะกดแป้นใด เมื่อเกิดเหตุการณ์เช่นนี้ คอมโพเนนต์จะกำหนด tabindex ของบุตรหลานที่โฟกัสอยู่ก่อนหน้าเป็น -1, ตั้งค่า tabindex ของบุตรหลานที่ต้องการโฟกัสเป็น 0 และเรียกใช้วิธีการโฟกัสในคอมโพเนนต์

<radio-group>
    <!-- Assuming the user pressed the down arrow, we'll focus the next available child -->
    <radio-button tabindex="-1">Water</radio-button>
    <radio-button tabindex="0">Coffee</radio-button> // call .focus() on this element
    <radio-button tabindex="-1">Tea</radio-button>
    <radio-button tabindex="-1">Cola</radio-button>
    <radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>

เมื่อผู้ใช้เลื่อนไปยังจุดย่อยสุดท้าย (หรือรายการแรก ขึ้นอยู่กับทิศทางที่พวกเขาย้ายโฟกัส) โฟกัสจะย้อนกลับไปที่ส่วนย่อยแรก (หรือสุดท้าย)

ลองดูตัวอย่างต่อไปนี้ ตรวจสอบองค์ประกอบใน DevTools เพื่อสังเกตว่า Tabindex เคลื่อนที่จากวิทยุหนึ่งไปยังวิทยุถัดไป

โมดัลและดักแป้นพิมพ์

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

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

ข้อยกเว้นสำหรับกฎนี้คือโมดัล อย่างไรก็ตาม คุณควรหลีกเลี่ยงการใช้ tabindex เมื่อสร้างโมดัล เมื่อใช้ inert คุณจะมั่นใจได้ว่าผู้ใช้จะไม่โต้ตอบกับองค์ประกอบโดยไม่ตั้งใจ (ดักจับแป้นพิมพ์โดยเจตนา) ใช้องค์ประกอบ <dialog> ซึ่งไม่มีการใช้งานโดยค่าเริ่มต้นเพื่อสร้างโมดัลสำหรับผู้ใช้ขณะที่บล็อกการคลิกและแท็บนอกโมดัล ซึ่งทำให้ผู้ใช้จดจ่อกับ การเลือกที่จำเป็น