โฟกัส

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

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

อย่าเปลี่ยนลำดับการกด Tab ที่รับรู้และที่แท้จริงด้วย CSS และ HTML ดังตัวอย่าง 2 รายการต่อไปนี้ ลำดับแท็บที่แตกต่างจากลำดับที่คาดหวังในเชิงภาพจะทำให้ผู้ใช้สับสนและส่งผลเสียต่อประสบการณ์ของผู้ใช้

ในตัวอย่างนี้ ค่าของแอตทริบิวต์ tabindex ทำให้ลำดับแท็บไม่เป็นระเบียบ

ในตัวอย่างนี้ CSS ได้สร้างความแตกต่างระหว่างลำดับการกด Tab กับ ลำดับภาพของเนื้อหา ดังนี้

ประกาศ flex-flow: row-reverse; ได้กลับลำดับภาพ นอกจากนี้ ยังมีการใช้พร็อพเพอร์ตี้ order ของ CSS กับคำที่ 6 ซึ่งก็คือ "This" ซึ่งทำให้คำนั้น เคลื่อนที่ไป ลำดับการกด Tab คือลำดับของโค้ด ซึ่งไม่ตรงกับลำดับภาพอีกต่อไป ทำให้ผู้ใช้แป้นพิมพ์ไม่สามารถใช้งานได้

ทำให้องค์ประกอบที่ไม่มีการโต้ตอบเป็นแบบอินเทอร์แอกทีฟ

แอตทริบิวต์ contenteditable และ tabindex เป็นแอตทริบิวต์ส่วนกลาง จึงเพิ่มลงในองค์ประกอบใดก็ได้ ทำให้องค์ประกอบเหล่านั้นสามารถโฟกัสได้ ในกระบวนการ นอกจากนี้ คุณยังโฟกัสองค์ประกอบที่โฟกัสได้ด้วยเมาส์หรือเคอร์เซอร์ได้โดยการตั้งค่าแอตทริบิวต์ autofocus หรือโดยสคริปต์ เช่น element.focus()

แอตทริบิวต์ tabindex

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

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

ในหน้านี้ ปุ่มแชร์ <share-action> เป็นองค์ประกอบที่กำหนดเอง tabindex="0" จะเพิ่มองค์ประกอบที่ปกติแล้วโฟกัสไม่ได้ นี้ลงในลำดับการกด Tab เริ่มต้นของแป้นพิมพ์

<share-action authors="@front-end.social/@estellevw" data-action="click" data-category="web.dev" data-icon="share" data-label="share, mastodon" role="button" tabindex="0">
  <svg aria-label="share" role="img" xmlns="http://www.w3.org/2000/svg">
    <use href="#shareIcon" />
  </svg>
  <span>Share</span>
</share-action>

นอกจากนี้ยังมีองค์ประกอบที่กำหนดเองอีกรายการในหน้านี้ โดยการนำทางในเครื่องมีองค์ประกอบที่กำหนดเองที่มีค่า tabindex เป็นลบ

<web-navigation-drawer type="standard" tabindex="-1">

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

คุณสามารถใช้เมธอด element.focus() เพื่อตั้งค่าโฟกัสไปยังองค์ประกอบที่โฟกัสได้ เบราว์เซอร์จะเลื่อนองค์ประกอบที่โฟกัส ไปยังมุมมอง ด้วยเหตุนี้ โปรดหลีกเลี่ยงการใช้ element.focus({preventScroll:true}) เนื่องจาก การโฟกัสที่องค์ประกอบที่มองไม่เห็นจะทำให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ไม่ดี

หากต้องการค้นหาเอกสารเพื่อดูว่าองค์ประกอบใดมีโฟกัส ให้ใช้พร็อพเพอร์ตี้ แบบอ่านอย่างเดียว Document.activeElement

องค์ประกอบที่มี tabindex ตั้งแต่ 1 ขึ้นไปจะรวมอยู่ในลำดับแท็บแยกต่างหาก ดังที่คุณจะเห็นใน Codepen การกด Tab จะเริ่มต้นในลำดับแยกต่างหาก โดยเรียงจากค่าต่ำสุดไปค่าสูงสุด ก่อนที่จะไปยังลำดับปกติ (ไม่มี tabindex หรือ tabindex="0") ตามลำดับในแหล่งที่มา

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

แอตทริบิวต์ contenteditable

เราได้พูดถึงแอตทริบิวต์ contenteditable ไปก่อนหน้านี้แล้ว การตั้งค่า contenteditable="true" ในองค์ประกอบใดก็ตามจะทำให้องค์ประกอบนั้นแก้ไขได้ โฟกัสได้ และเป็นส่วนหนึ่งของลำดับการกดแป้น Tab ลักษณะการทำงานของโฟกัสจะคล้ายกับการตั้งค่า tabindex="0" แต่ไม่เหมือนกัน องค์ประกอบ contenteditable ที่ซ้อนกันจะโฟกัสได้แต่กด Tab ไม่ได้ หากต้องการทำให้องค์ประกอบ contenteditable ที่ซ้อนกันสามารถกด Tab ได้ ให้เพิ่ม tabindex="0" ซึ่งจะเพิ่มองค์ประกอบดังกล่าวลงในลำดับการนำทางโฟกัสตามลำดับ

ให้ autofocus แก่องค์ประกอบแบบอินเทอร์แอกทีฟ

แม้ว่าบูลีน autofocus จะเป็นแอตทริบิวต์ส่วนกลาง ที่ตั้งค่าในองค์ประกอบใดก็ได้ แต่ก็ไม่ได้ทําให้องค์ประกอบที่ไม่มีการโต้ตอบกลายเป็นแบบอินเทอร์แอกทีฟ เมื่อหน้าเว็บโหลด องค์ประกอบแรกที่โฟกัสได้ ซึ่งมีแอตทริบิวต์ autofocus จะได้รับโฟกัส ตราบใดที่องค์ประกอบนั้นแสดงอยู่และไม่ได้ซ้อนอยู่ใน <dialog>

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

ข้อยกเว้นของคำแนะนำ "อย่าใช้ autofocus" คือการใส่แอตทริบิวต์ autofocus ภายในองค์ประกอบ <dialog> เมื่อเปิดกล่องโต้ตอบ เบราว์เซอร์จะโฟกัสที่องค์ประกอบเชิงโต้ตอบแรกที่โฟกัสได้ภายใน <dialog> โดยอัตโนมัติ ซึ่งหมายความว่าไม่จำเป็นต้องเพิ่ม autofocus ลงในองค์ประกอบ หากต้องการให้องค์ประกอบแบบอินเทอร์แอกทีฟที่เฉพาะเจาะจงภายในกล่องโต้ตอบได้รับโฟกัสเมื่อกล่องโต้ตอบเปิดขึ้น ให้เพิ่มแอตทริบิวต์ autofocus ลงในองค์ประกอบนั้น

<dialog open>
  <form method="dialog">
    <button type="submit" autofocus>close</button>
  </form>
</dialog>

แอตทริบิวต์ autofocus ที่ตั้งค่าไว้ใน <button> close จะช่วยให้รับโฟกัสได้ เมื่อเปิดกล่องโต้ตอบ เนื่องจากเป็นองค์ประกอบแรกในกล่องโต้ตอบ จึงจะได้รับโฟกัสในทุกกรณี โดยค่าเริ่มต้น เมื่อเปิดกล่องโต้ตอบ องค์ประกอบแรกที่ โฟกัสได้ภายในกล่องโต้ตอบจะได้รับโฟกัส เว้นแต่ว่าองค์ประกอบอื่น ภายในกล่องโต้ตอบจะมีการตั้งค่าแอตทริบิวต์ autofocus

ทำให้องค์ประกอบแบบอินเทอร์แอกทีฟไม่ทำงาน

นอกจากนี้ ยังมีแอตทริบิวต์ HTML ที่นำองค์ประกอบแบบอินเทอร์แอกทีฟออกจากลำดับการกด Tab ได้ด้วย การใส่ค่าลบ tabindex ในองค์ประกอบที่โฟกัสได้ การเพิ่มแอตทริบิวต์ disabled ลงในตัวควบคุมแบบฟอร์มที่รองรับ และการเพิ่มแอตทริบิวต์ inert ส่วนกลาง ลงในคอนเทนเนอร์จะทำให้องค์ประกอบทั้งหมดไม่สามารถใช้แป้น Tab ได้ แอตทริบิวต์ทั้ง 3 รายการนี้ใช้แทนกันไม่ได้

ค่า tabindex เป็นลบ

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

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

ปิดใช้

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

disabled ไม่ใช่แอตทริบิวต์ส่วนกลาง โดยจะมีผลกับ <button>, <input>, <optgroup>, <option>, <select>, <textarea>, องค์ประกอบที่กำหนดเองที่เชื่อมโยงกับแบบฟอร์ม และ <fieldset> เมื่อตั้งค่าใน <optgroup> หรือ <fieldset> ระบบจะปิดใช้ตัวควบคุมแบบฟอร์มย่อยทั้งหมด ยกเว้นเนื้อหาของ<legend>แรกของ <fieldset>

องค์ประกอบเดียวกันที่รองรับ disabled ยังกำหนดเป้าหมายได้ด้วย :disabled และ:enabled คลาสเสมือน โดยทั่วไปแล้ว องค์ประกอบที่ปิดใช้ด้วยแอตทริบิวต์ disabled จะมีลักษณะเป็นสีเทาอ่อนพร้อมกับชีตสไตล์ของ User Agent แม้ว่าจะมีการตั้งค่า accent-color ไว้ก็ตาม

เนื่องจากเป็นแอตทริบิวต์บูลีน การมีแอตทริบิวต์นี้จะปิดใช้องค์ประกอบที่เปิดใช้อยู่ คุณจึงตั้งค่าเป็น false ไม่ได้ หากต้องการเปิดใช้องค์ประกอบที่ปิดใช้ คุณต้องนำแอตทริบิวต์ออก โดยทั่วไปจะใช้ Element.removeAttribute('disabled')

พร็อพเพอร์ตี้ HTMLInputElement.disabled ช่วยให้คุณตรวจสอบได้ว่าอินพุตถูกปิดใช้หรือไม่ เนื่องจาก disabled ไม่ใช่แอตทริบิวต์ส่วนกลาง จึงไม่ได้สืบทอดมาจาก HTMLElement แต่ทุกอินเทอร์เฟซขององค์ประกอบที่รองรับ เช่น HTMLSelectElement, HTMLTextareaElement จะมีพร็อพเพอร์ตี้แบบอ่านอย่างเดียวเดียวกัน

แอตทริบิวต์ disabled จะไม่มีผลกับองค์ประกอบ inert ที่ปกติแล้วจะ ทำให้โฟกัสได้ด้วย tabindex หรือ contenteditable และจะไม่มีผลกับองค์ประกอบ <form> ด้วย หากต้องการปิดใช้องค์ประกอบเหล่านี้ คุณสามารถใช้แอตทริบิวต์ inert ทั่วโลกได้

แอตทริบิวต์ inert

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

เมื่อใช้ disabled กับตัวควบคุมแบบฟอร์ม เบราว์เซอร์จะให้รูปแบบเริ่มต้น และสามารถจัดรูปแบบได้โดยใช้คลาสเสมือน :disabled แอตทริบิวต์ inert ไม่ได้ระบุภาพและไม่มี Pseudoclass ที่ตรงกัน (แม้ว่า[inert] ตัวเลือกแอตทริบิวต์จะตรงกัน)

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

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

ทดสอบความเข้าใจ

ทดสอบความรู้เกี่ยวกับโฟกัส

หากโฟกัสองค์ประกอบไม่ได้ ระบบจะอธิบายว่าองค์ประกอบนั้นเป็นอะไร

ว่าง
โปรดลองอีกครั้ง
เฉื่อย
ถูกต้อง
ซ่อนอยู่
โปรดลองอีกครั้ง

อะไรจะเป็นจริงหากองค์ประกอบมีแอตทริบิวต์ disabled

และจะโฟกัสไม่ได้
ถูกต้อง
ระบบจะไม่แสดงข้อมูลนี้
โปรดลองอีกครั้ง
หากเป็นองค์ประกอบของแบบฟอร์ม ระบบจะไม่ส่ง
ถูกต้อง