โฟกัส

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

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

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

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

ในตัวอย่างนี้ CSS ทำให้ลำดับการใช้แท็บและลำดับการแสดงผลของเนื้อหาแตกต่างกัน

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

ฟีเจอร์ CSS บางอย่าง รวมถึง Flexbox, Grid, Positioning, Transforms, และ Multi-column, สามารถเปลี่ยนลำดับการแสดงผลของเนื้อหาได้ ทดสอบเนื้อหาโดยใช้แท็บผ่านเนื้อหา ด้วยแป้นพิมพ์ โดยใช้ Shift + Tab เพื่อย้ายผ่านเนื้อหาไปข้างหลัง ใช้ CSS เพื่อระบุว่าองค์ประกอบใดที่โฟกัสอยู่ อย่าจัดลำดับองค์ประกอบที่โฟกัสได้ใหม่ด้วย CSS

คุณต้องรักษาลำดับการใช้แท็บเชิงตรรกะในขนาดวิวพอร์ตทั้งหมด

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ค่า tabindex เป็นค่าลบ

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

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

ปิดใช้

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

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

องค์ประกอบเดียวกันที่รองรับ 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 แบบบูลีนส่วนกลางลงในองค์ประกอบ องค์ประกอบนั้นและเนื้อหาที่ซ้อนกันทั้งหมดจะถูกปิดใช้ ซึ่งหมายความว่าคลิกหรือใช้แท็บเพื่อไปยังองค์ประกอบเหล่านั้นไม่ได้ นอกจากนี้ ระบบยังนำองค์ประกอบเหล่านั้นออกจากแผนผังการช่วยเหลือพิเศษด้วย แม้ว่าคุณจะใช้ inert กับองค์ประกอบใดก็ได้ แต่โดยทั่วไปจะใช้กับส่วนของเนื้อหา เช่น เนื้อหาที่อยู่นอกหน้าจอหรือเนื้อหาที่ซ่อน

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

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

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

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

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

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

ว่างเปล่า
โปรดลองอีกครั้ง
ไม่ทำงาน
ถูกต้อง
ซ่อนอยู่
โปรดลองอีกครั้ง

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

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