คำขอความคิดเห็นจากนักพัฒนาแอป: focusgroup

Jacques Newman
Jacques Newman

เผยแพร่: 5 มีนาคม 2026

focusgroupแอตทริบิวต์ HTML เป็นวิธีประกาศที่เสนอเพื่อเพิ่มการนำทางด้วยแป้นลูกศรของคีย์บอร์ดไปยังวิดเจ็ตแบบคอมโพสิต เช่น แถบเครื่องมือ รายการแท็บ เมนู กล่องรายการ ฯลฯ โดยไม่ต้องเขียน JavaScript roving-tabindex แอตทริบิวต์เดียว แทนที่ Boilerplate หลายร้อยบรรทัด เราอยากฟังความคิดเห็นจากคุณก่อนที่จะเปิดตัวฟีเจอร์นี้

ลองใช้และส่งความคิดเห็นถึงเรา

คุณลองใช้ focusgroup ได้แล้ววันนี้ใน Chrome, Edge และเบราว์เซอร์ Chromium อื่นๆ โดย เปิดใช้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้

  1. การทดสอบในเครื่อง: เปิดหน้า about://flags ในเบราว์เซอร์ แล้วเปิดใช้ Flag ฟีเจอร์แพลตฟอร์มเว็บเวอร์ชันทดลอง หรือเปิดเบราว์เซอร์จากบรรทัดคำสั่งโดยใช้พารามิเตอร์บรรทัดคำสั่ง --enable-blink-features=Focusgroup
  2. ช่วงทดลองใช้จากต้นทาง: ลงทะเบียนช่วงทดลองใช้จากต้นทางของโฟกัสกรุ๊ป เพื่อทดสอบในเว็บไซต์กับผู้ใช้จริง

จากนั้นสำรวจการสาธิตแบบอินเทอร์แอกทีฟ เพื่อดูรูปแบบทั้งหมดในการทำงาน

เราต้องการความคิดเห็นจากคุณ ยื่นปัญหาการสนทนากลุ่ม เพื่อบอกให้เราทราบว่าคุณคิดอย่างไร

นี่คือความพยายามข้ามเบราว์เซอร์: ข้อเสนอมาจาก Microsoft ผ่านกลุ่มชุมชน OpenUI โดยได้รับการสนับสนุนอย่างเต็มที่ จาก Google รูปร่างของ API อาจเปลี่ยนแปลงตามความคิดเห็นของคุณ มาดูปัญหาที่โฟกัสกรุ๊ปช่วยแก้และวิธีทำงานของ API กัน

ปัญหา: roving tabindex ด้วยตนเอง

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

<div role="toolbar" aria-label="Text formatting" id="toolbar">
  <button type="button" tabindex="0">Bold</button>
  <button type="button" tabindex="-1">Italic</button>
  <button type="button" tabindex="-1">Underline</button>
  <button type="button" tabindex="-1">Strikethrough</button>
</div>

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

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

ไลบรารี UI ส่วนใหญ่ รวมถึง React Angular CDK และ Fluent UI แต่ละรายการ จะมาพร้อมกับตรรกะเวอร์ชันของตนเอง ซึ่งเป็นการทำงานที่ซ้ำซ้อนเป็นอย่างมากเพื่อรับ สิ่งที่อาจเป็นองค์ประกอบพื้นฐานของแพลตฟอร์ม

วิธีแก้ปัญหา: แอตทริบิวต์ focusgroup

เมื่อใช้ focusgroup แถบเครื่องมือเดียวกันจะกลายเป็น

<div focusgroup="toolbar" aria-label="Text formatting">
  <button type="button">Bold</button>
  <button type="button">Italic</button>
  <button type="button">Underline</button>
  <button type="button">Strikethrough</button>
</div>
แถบเมนูที่โฟกัสปุ่มตัวเอียง

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

  • การไปยังส่วนต่างๆ ด้วยปุ่มลูกศร: ไปยังส่วนต่างๆ โดยคำนึงถึงโหมดการเขียนและทิศทาง
  • การหยุดแท็บเดียว: เบราว์เซอร์จะยุบรายการที่เข้าร่วมให้เหลือการหยุดแท็บเดียวโดยอัตโนมัติ นักพัฒนาแอปไม่จำเป็นต้องตั้งค่า tabindex="-1" ใน ไอเทมที่ไม่ได้ใช้งาน
  • การจดจำรายการที่โฟกัสล่าสุด: เมื่อผู้ใช้ออกจากโฟกัสกรุ๊ปและกลับมา ระบบจะคืนค่าโฟกัสไปยังรายการที่ผู้ใช้ทิ้งไว้
  • ความหมายของ ARIA: เบราว์เซอร์จะจัดเตรียมบทบาทที่เหมาะสม (เช่น role="toolbar") ตามลักษณะการทำงานที่เลือกเมื่อใช้องค์ประกอบทั่วไป

นักพัฒนาซอฟต์แวร์จะเก็บเฉพาะตรรกะที่เป็นเอกลักษณ์ของฟีเจอร์ของตน เช่น การสลับสถานะที่กด การเปิดเมนู การจัดการการเลือก หรือคำสั่งที่กำหนดเอง

ภาพรวมของ API

แอตทริบิวต์ focusgroup จะใช้รายการโทเค็นที่คั่นด้วยช่องว่าง โทเค็นแรกจะเป็นโทเค็นลักษณะการทำงานที่ประกาศรูปแบบวิดเจ็ตเสมอ โทเค็นตัวแก้ไขที่ไม่บังคับ มีดังนี้ focusgroup="<behavior> [inline|block] [wrap] [nomemory]"

โทเค็นพฤติกรรม

ต้องระบุโทเค็นพฤติกรรม (เว้นแต่จะใช้ none เพื่อเลือกไม่ใช้กลุ่มโฟกัสของบรรพบุรุษ ) โดยจะประกาศรูปแบบวิดเจ็ตแบบคอมโพสิตเพื่อให้มั่นใจว่าระบบจะอนุมานบทบาทที่ถูกต้องได้เมื่อไม่ได้ระบุไว้ โทเค็นเป็นไปตาม รูปแบบที่อธิบายไว้ใน คู่มือแนวทางปฏิบัติในการเขียน ARIA และแสดงอยู่ในตารางต่อไปนี้

พฤติกรรม รูปแบบ APG บทบาทคอนเทนเนอร์ขั้นต่ำ (เมื่อใช้) บทบาทขั้นต่ำของบัญชีลูก
(เมื่อใช้)
ตัวปรับเริ่มต้น
toolbar แถบเครื่องมือ แถบเครื่องมือ (ไม่มี) inline
tablist แท็บ APG tablist แท็บ inline wrap
radiogroup กลุ่มปุ่มตัวเลือก radiogroup วิทยุ (ไม่มี)
listbox กล่องรายการ listbox option (ไม่มี)
menu เมนู เมนู menuitem block wrap
menubar แถบเมนู menubar menuitem inline wrap
none ไม่มี ไม่มี ไม่มี ไม่มี

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

การจำกัดแกน (inline และ block)

หากลักษณะการทำงานที่เลือกไม่มีตัวแก้ไขเริ่มต้นใดๆ ปุ่มลูกศรทั้ง 4 ปุ่ม จะใช้ได้ในการย้ายโฟกัส คุณจำกัดการไปยังแกนตรรกะเดียวได้โดย ใช้ตัวแก้ไข inline หรือ block

  • inline: Focusgroup จะตอบสนองต่อปุ่มลูกศรในแกนแบบอินไลน์เท่านั้น ซ้ายและขวาในบริบทภาษาอังกฤษส่วนใหญ่ (แนวนอน จากบนลงล่าง)
  • block: กลุ่มโฟกัสจะตอบสนองต่อปุ่มลูกศรในแกนบล็อกเท่านั้น ขึ้นและลงในบริบทภาษาอังกฤษส่วนใหญ่ (แนวนอน จากบนลงล่าง)

การจำกัดแกนสอดคล้องกับพร็อพเพอร์ตี้เชิงตรรกะของ CSS และปรับให้เข้ากับโหมดและทิศทางการเขียนโดยอัตโนมัติ

การนำทางแบบวนรอบ

โดยค่าเริ่มต้น การไปยังส่วนต่างๆ ด้วยปุ่มลูกศรจะหยุดที่ขอบของ FocusGroup เพิ่มตัวปรับแต่ง wrap เพื่อวนซ้ำจากรายการสุดท้ายกลับไปที่รายการแรก (และจากรายการแรก กลับไปที่รายการสุดท้าย) หากลักษณะการทำงานมีการตัดข้อความโดยค่าเริ่มต้น ให้ใช้ตัวแก้ไข nowrap เพื่อปิดใช้ลักษณะการทำงานนี้

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

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

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

<div focusgroup="toolbar nomemory" aria-label="Entry point demo">
  <button type="button">First</button>
  <button type="button" focusgroupstart>Middle (Entry)</button>
  <button type="button">Last</button>
</div>
แถบเมนูที่มีปุ่มกลางเป็นโฟกัส

ทั้ง Tab และ Shift+Tab จะไปที่ "กลาง (รายการ)" เนื่องจากมี focusgroupstart และปิดใช้หน่วยความจำด้วยตัวแก้ไข nomemory ลองใช้จริง รูปแบบแถบเครื่องมือ > จุดแรกเข้าที่มี focusgroupstart

ปิดใช้หน่วยความจำ (nomemory)

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

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

เลือกไม่ใช้ (focusgroup="none")

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

<div focusgroup="toolbar" aria-label="Segmented toolbar">
  <button type="button">New</button>
  <button type="button">Open</button>
  <button type="button">Save</button>
  <span focusgroup="none">
    <button type="button">Help</button>
    <button type="button">Shortcuts</button>
  </span>
  <button type="button">Close</button>
  <button type="button">Exit</button>
</div>
เมนูที่มีปุ่มความช่วยเหลือและปุ่มลัดเป็นสีเทา

การใช้ปุ่มลูกศรขวาจะไปยังตัวเลือกใหม่ จากนั้นเปิด บันทึก ปิด และออก โดยข้ามปุ่มความช่วยเหลือและแป้นพิมพ์ลัดไปทั้งหมด แต่ผู้ใช้ยังคงกด Tab ไปยังส่วนความช่วยเหลือเพื่อเข้าถึงปุ่มเหล่านี้ได้ ลองใช้แบบเรียลไทม์ แนวคิดเพิ่มเติม > กลุ่มที่เลือกไม่ใช้ที่มี focusgroup="none"

รูปแบบที่พบบ่อย

Tablist

ตัวควบคุมแท็บที่มีการไปยังส่วนต่างๆ ระหว่างแท็บด้วยปุ่มลูกศร

<div focusgroup="tablist nomemory" aria-label="Sections">
  <button type="button" aria-selected="true" aria-controls="panel-overview" id="tab-overview" focusgroupstart>Overview</button>
  <button type="button" aria-selected="false" aria-controls="panel-features" id="tab-features">Features</button>
  <button type="button" aria-selected="false" aria-controls="panel-pricing" id="tab-pricing">Pricing</button>
  <button type="button" aria-selected="false" aria-controls="panel-faq" id="tab-faq">FAQ</button>
</div>
<div role="tabpanel" id="panel-overview" aria-labelledby="tab-overview" tabindex="0">...</div>
<div role="tabpanel" id="panel-features" aria-labelledby="tab-features" tabindex="0">...</div>
<div role="tabpanel" id="panel-pricing" aria-labelledby="tab-pricing" tabindex="0">...</div>
<div role="tabpanel" id="panel-faq" aria-labelledby="tab-faq" tabindex="0">...</div>
แท็บภาพรวมอยู่ในโฟกัส

ลองใช้จริง: รูปแบบ Tablist > Tablist แนวนอนที่มี การตัดข้อความ

สิ่งที่ควรสังเกต

  • แอตทริบิวต์ focusgroupstart อยู่ในแท็บเลือก ดังนั้นโฟกัสจะเข้าสู่แท็บนี้เสมอ
  • ตัวแก้ไข nomemory จะช่วยให้มั่นใจได้ว่าแม้ว่าก่อนหน้านี้ผู้ใช้จะโฟกัส แท็บอื่นอยู่ แต่การกลับเข้ามาจะไปยังแท็บที่เลือกเสมอ
  • ตัวแก้ไข inline จะจำกัดการไปยังส่วนต่างๆ ด้วยลูกศรไว้ที่ปุ่มซ้ายและขวาเท่านั้น ซึ่งตรงกับลักษณะการทำงานที่คาดไว้ตามรูปแบบแท็บ APG
  • wrap ตัวแก้ไขช่วยให้ผู้ใช้ใช้ปุ่มลูกศรได้อย่างต่อเนื่องในแท็บทั้งหมด
  • โค้ดของนักพัฒนาแอปซึ่งละไว้เพื่อความกระชับจะจัดการการเลือกจริง ได้แก่ การอัปเดต aria-selected การสลับการแสดงแผง และการย้ายแอตทริบิวต์ focusgroupstart เมื่อมีการเปลี่ยนแปลงการเลือก

เมนูแนวตั้งแบบเรียบง่ายพร้อมการนำทางด้วยลูกศรขึ้นและลง

<div focusgroup="menu" aria-label="File actions" class="menu-vertical">
    <button type="button" class="menu-item">New</button>
    <button type="button" class="menu-item">Open…</button>
    <button type="button" class="menu-item">Save</button>
    <button type="button" class="menu-item">Exit</button>
</div>
เมนูแนวตั้งที่มีรายการเมนู &quot;เปิด&quot; อยู่

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

<ul role="menubar" focusgroup="menubar"
     aria-label="Application Menu" class="menubar">
    <li role="none">
        <button role="menuitem" type="button" class="menubar-item"
             aria-haspopup="menu" aria-expanded="false"
             popovertarget="filemenu">File</button>
        <ul role="menu" focusgroup="menu"
             id="filemenu" popover aria-label="File submenu" class="submenu">
            <li role="none"><button type="button" class="submenu-item"
                 autofocus>New</button></li>
            <li role="none"><button type="button" class="submenu-item">Open</button></li>
            <li role="none"><button type="button" class="submenu-item">Save</button></li>
        </ul>
    </li>
    <!-- More menu items... -->
</ul>
เมนูแบบเลื่อนลงที่มีรายการคัดลอกที่โฟกัส

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

Radiogroup

กลุ่มปุ่มตัวเลือกที่กำหนดเองพร้อมการนำทางด้วยปุ่มลูกศรและการควบคุมการจัดรูปแบบทั้งหมด

<div focusgroup="radiogroup" aria-label="Favorite color">
  <span aria-checked="false" tabindex="0">Red</span>
  <span aria-checked="false" tabindex="0">Green</span>
  <span aria-checked="true" tabindex="0" focusgroupstart >Blue</span>
  <span aria-checked="false" tabindex="0">Purple</span>
</div>
กลุ่มปุ่มตัวเลือกที่มีสีน้ำเงินเป็นโฟกัส

ลองใช้จริง:0x0A>รูปแบบกลุ่มปุ่มตัวเลือก > การเปรียบเทียบ: เนทีฟเทียบกับ Focusgroup

แม้ว่าแอตทริบิวต์ focusgroup จะจัดการการนำทางด้วยแป้นลูกศร แต่คุณต้อง ใช้โค้ดการเลือก ในเดโมนี้ โค้ด JavaScript จะจัดการสถานะที่เลือก (โดยใช้แอตทริบิวต์ aria-checked)

หัวข้อสำคัญ

การเข้าร่วมการสนทนากลุ่ม

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

แท็บหยุด

คุณไม่จำเป็นต้องจัดการค่า tabindex แม้ว่าลูกหลานหลายคนจะแท็บได้ตามปกติ (เช่น องค์ประกอบ <button> หลายรายการ) focusgroup จะยุบองค์ประกอบเหล่านั้นให้เป็นจุดหยุดแท็บเดียว เบราว์เซอร์จะจัดการว่ารายการใดที่ กด Tab ได้ในแต่ละช่วงเวลา ลองใช้จริง รูปแบบแถบเครื่องมือ > ไม่จำเป็นต้องจัดการ tabindex

หน่วยความจำที่โฟกัสล่าสุด

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

การสนทนากลุ่มที่ซ้อนกัน

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

รองรับ Shadow DOM

Focusgroup จะใช้ข้ามขอบเขต Shadow DOM โดยค่าเริ่มต้น กลุ่มโฟกัสที่ประกาศในโฮสต์เงาจะมีองค์ประกอบที่โฟกัสได้ภายใน Shadow Tree ของโฮสต์นั้น หากต้องการเลือกไม่ใช้ คุณสามารถใช้ focusgroup="none" ภายใน Shadow Tree ของคอมโพเนนต์

การจัดการความขัดแย้งที่สำคัญ

องค์ประกอบบางอย่างภายในโฟกัสกรุ๊ป เช่น <input>, <textarea> และตัวควบคุมอื่นๆ จะใช้แป้นลูกศรเพื่อวัตถุประสงค์ของตนเอง เมื่อแป้นนำทางของ focusgroup ขัดแย้งกับลักษณะการทำงานของแป้นลูกศรขององค์ประกอบเนทีฟ ให้ทำดังนี้

  • องค์ประกอบแบบอินเทอร์แอกทีฟจะใช้ปุ่มลูกศร (เช่น สำหรับการเคลื่อนเคอร์เซอร์ข้อความ) และ focusgroup จะไม่รบกวน
  • Tab หรือ Shift+Tab จะมีกลไกการหลุดออกจากโฟกัสเริ่มต้น ซึ่งช่วยให้ผู้ใช้ ใช้การไปยังส่วนต่างๆ ด้วย Tab เพื่อ "กลับเข้าไป" ในโฟกัสกรุ๊ปได้

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

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

การค้นหาผู้สืบสกุลแบบละเอียด

รายการ Focusgroup ไม่จำเป็นต้องเป็นองค์ประกอบย่อยโดยตรงของคอนเทนเนอร์ Focusgroup

เบราว์เซอร์จะพิจารณาองค์ประกอบย่อยที่โฟกัสได้ตามลำดับทั้งหมด (ค่าที่ไม่ใช่ค่าลบ tabindex) ให้เข้าร่วม focusgroup เว้นแต่จะอยู่ใน focusgroup ที่ซ้อนกันหรือเลือกไม่ใช้ด้วย focusgroup="none"

<div focusgroup="toolbar" aria-label="Nested wrappers">
  <div>
    <span>
      <button type="button">Alpha</button>
    </span>
    <span>
      <button type="button">Beta</button>
    </span>
    <span>
      <button type="button">Gamma</button>
    </span>
  </div>
</div>

การนำทางด้วยปุ่มลูกศรจะทำงานแม้ว่าปุ่มจะซ้อนอยู่ภายใน Wrapper <div> และ <span> ไม่จำเป็นต้องใช้รายการแบบแบน ดังนั้นจึงใช้องค์ประกอบ Wrapper สำหรับ การจัดรูปแบบได้

ลองใช้แบบเรียลไทม์ แนวคิดเพิ่มเติม > ลูกหลานที่สืบเชื้อสายมา

การผสานรวมกับพร็อพเพอร์ตี้ reading-flow

การไปยังส่วนต่างๆ ทั้งแบบลำดับ (Tab) และแบบทิศทาง (ปุ่มลูกศร) จะพิจารณาพร็อพเพอร์ตี้ CSS reading-flow เมื่อมีอยู่ โดยจะทำตามลำดับการอ่านภาพแทนที่จะเป็นลำดับแหล่งที่มาของ DOM

ซึ่งช่วยให้มั่นใจได้ว่าการไปยังส่วนต่างๆ ด้วยปุ่มลูกศรจะตรงกับเลย์เอาต์ที่ผู้ใช้เห็นบนหน้าจอ

<div focusgroup="toolbar" aria-label="Visual order"
     style="display: flex; flex-direction: row-reverse; reading-flow: flex-visual;">
  <button type="button">A (DOM first)</button>
  <button type="button">B (DOM second)</button>
  <button type="button">C (DOM third)</button>
</div>
รายการ ก กำลังโฟกัสอยู่

แม้ว่าลำดับ DOM จะเป็น ก ข ค แต่ลำดับภาพจะเป็น ค ข ก เนื่องจากเลย์เอาต์ใช้ flex-direction: row-reverse อย่างไรก็ตาม เนื่องจากโค้ดยังใช้ reading-flow: flex-visualด้วย ลำดับการอ่านจึงกลับไปเป็น A, B, C และ focusgroup จะตรงกับลำดับนี้

การกด Tab จะโฟกัสที่ C ก่อน จากนั้นการกดขวาจะโฟกัสที่ B แล้วจึงโฟกัสที่ A ลองใช้จริง แนวคิดเพิ่มเติม > การผสานรวมโฟลว์การอ่าน CSS

การช่วยเหลือพิเศษ

การอนุมานบทบาท ARIA

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

<div focusgroup="tablist">
  <button>Tab 1</button>
  <button>Tab 2</button>
  <button>Tab 3</button>
</div>

สร้างแผนผังการช่วยเหลือพิเศษต่อไปนี้ แม้ว่าจะไม่ได้กำหนดบทบาทใดๆ ไว้ใน ปุ่มก็ตาม

+   tablist
  |
  +   tab
  |
  +   tab
  |
  +   tab

คุณควบคุมลักษณะการทำงานได้ทุกเมื่อโดยกำหนดบทบาทโดยตรง

ข้อควรพิจารณาเกี่ยวกับการช่วยเหลือพิเศษ

โปรดระมัดระวังในการปฏิบัติตามพฤติกรรมที่คุณเลือกเมื่อสร้างกลุ่มโฟกัส

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

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

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

การตรวจหาฟีเจอร์

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

if ('focusgroup' in HTMLElement.prototype) {
  // focusgroup is supported.
} else {
  // fall back to manual roving tabindex.
}

บทสรุป

แอตทริบิวต์ focusgroup กำลังอยู่ระหว่างการพิจารณาโดยหน่วยงานด้านมาตรฐาน และเรา กำลังสร้างต้นแบบใน Chromium และปรับแต่ง API อย่างต่อเนื่อง

ลองใช้และแจ้งปัญหาของกลุ่มทดสอบ ในเครื่องมือติดตามปัญหา GitHub ของ Open-UI เราสนใจความคิดเห็นของคุณเกี่ยวกับประเด็นต่อไปนี้เป็นพิเศษ

  • API ที่คุณใช้รู้สึกว่าเหมาะกับรูปแบบที่คุณสร้างหรือไม่
  • มีรูปแบบหรือสถานการณ์ใดที่เรามองข้ามไปไหม
  • มีองค์ประกอบที่ไม่ควรอนุญาตให้ใช้แอตทริบิวต์ focusgroup ไหม
  • เรื่องราวการช่วยเหลือพิเศษเหมาะกับกรณีการใช้งานของคุณอย่างไร

ขอขอบคุณที่ช่วยปรับปรุงการไปยังส่วนต่างๆ บนเว็บด้วยแป้นพิมพ์

ดูข้อมูลเพิ่มเติม

ขอขอบคุณ Mason Freed, Sara Higley, Scott O'Hara และคนอื่นๆ ในชุมชน Open-UI ที่ช่วยให้เรานำ focusgroup กลับมาได้