เผยแพร่: 1 พฤษภาคม 2025
พร็อพเพอร์ตี้ CSS reading-flow และ reading-order พร้อมใช้งานใน Chrome 137
โพสต์นี้จะอธิบายเหตุผลที่อยู่เบื้องหลังการออกแบบพร็อพเพอร์ตี้เหล่านี้ และรายละเอียดโดยย่อบางส่วนเพื่อช่วยให้คุณเริ่มต้นใช้งานได้
วิธีการจัดเลย์เอาต์ เช่น กริดและ Flex ได้เปลี่ยนโฉมการพัฒนาส่วนหน้า แต่ความยืดหยุ่นของเลย์เอาต์อาจทำให้เกิดปัญหาสำหรับผู้ใช้บางราย การสร้างสถานการณ์ที่ลำดับภาพไม่ตรงกับลำดับแหล่งที่มาใน DOM tree เป็นเรื่องง่ายมาก เนื่องจากลำดับแหล่งที่มานี้เป็นสิ่งที่เบราว์เซอร์ทำตามหากคุณไปยังส่วนต่างๆ ของเว็บไซต์โดยใช้แป้นพิมพ์ ผู้ใช้บางรายจึงอาจพบการข้ามไปมาที่ไม่คาดคิดขณะไปยังส่วนต่างๆ ของหน้า
เราได้ออกแบบและเพิ่มพร็อพเพอร์ตี้ reading-flow และ reading-order ลงในข้อกำหนดการแสดงผล CSS เพื่อพยายามแก้ไขปัญหานี้ที่เกิดขึ้นมานาน
reading-flow
พร็อพเพอร์ตี้ reading-flow CSS จะควบคุมลำดับที่องค์ประกอบในเลย์เอาต์ Flex, Grid
หรือ Block จะแสดงต่อเครื่องมือช่วยการเข้าถึง และวิธีที่องค์ประกอบจะได้รับโฟกัส
โดยใช้วิธีการนำทางแบบลำดับเชิงเส้น
โดยจะใช้ค่าคีย์เวิร์ด 1 ค่า ซึ่งมีค่าเริ่มต้นเป็น normal ซึ่งจะคงลักษณะการทำงานของการจัดเรียงองค์ประกอบตามลำดับ DOM
หากต้องการใช้ภายในคอนเทนเนอร์ Flex ให้ตั้งค่าเป็น flex-visual หรือ flex-flow หากต้องการใช้ภายในคอนเทนเนอร์กริด ให้ตั้งค่าเป็น grid-rows, grid-columns หรือ grid-order
reading-order
reading-order พร็อพเพอร์ตี้ CSS ช่วยให้คุณลบล้างลำดับของ
รายการภายในคอนเทนเนอร์โฟลว์การอ่านได้ด้วยตนเอง หากต้องการใช้พร็อพเพอร์ตี้นี้ภายในกริด Flex
หรือคอนเทนเนอร์บล็อก ให้ตั้งค่า reading-flow ในคอนเทนเนอร์เป็น
source-order และตั้งค่า reading-order ของแต่ละรายการเป็นค่าจำนวนเต็ม
ตัวอย่างใน Flexbox
ตัวอย่างเช่น คุณอาจมีคอนเทนเนอร์เลย์เอาต์ Flex ที่มีองค์ประกอบ 3 รายการใน ลำดับแถวย้อนกลับ และต้องการใช้พร็อพเพอร์ตี้ลำดับเพื่อสับเปลี่ยน ลำดับนั้นใหม่ด้วย
<div class="box">
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</div>
.box {
display: flex;
flex-direction: row-reverse;
}
.box :nth-child(1) {
order: 2;
}
คุณลองไปยังองค์ประกอบเหล่านี้โดยใช้แป้น TAB เพื่อค้นหาองค์ประกอบที่โฟกัสได้ถัดไป และแป้น TAB+SHIFT เพื่อค้นหาองค์ประกอบที่โฟกัสได้ก่อนหน้า โดยจะเรียงตามลำดับในแหล่งที่มา ได้แก่ หนึ่ง สอง สาม
จากมุมมองของผู้ใช้ปลายทาง การดำเนินการนี้ไม่สมเหตุสมผลและอาจสร้างความสับสนเป็นอย่างมาก และจะเกิดสิ่งเดียวกันนี้หากเราใช้เครื่องมือการนำทางเชิงพื้นที่เพื่อการช่วยเหลือพิเศษ เพื่อไปยังส่วนต่างๆ ของหน้า
หากต้องการแก้ไขปัญหานี้ ให้ตั้งค่าพร็อพเพอร์ตี้ reading-flow ดังนี้
.box {
reading-flow: flex-visual;
}
ตอนนี้ลำดับการโฟกัสคือ 1, 3, 2 ซึ่งจะเหมือนกับลำดับภาพ ที่คุณจะเห็นหากอ่านภาษาอังกฤษจากซ้ายไปขวา
หากต้องการให้ลำดับโฟกัสเป็นไปตามที่ตั้งใจไว้แต่แรกใน ลำดับย้อนกลับ คุณสามารถตั้งค่าดังนี้
.box {
reading-flow: flex-flow;
}
ตอนนี้ลำดับโฟกัสเป็นลำดับย้อนกลับของ Flex แล้ว ได้แก่ 2, 3, 1 ใน
ทั้ง 2 กรณี ระบบจะพิจารณาพร็อพเพอร์ตี้ order ของ CSS
ตัวอย่างที่มีเลย์เอาต์ตารางกริด
หากต้องการดูว่าการทำงานนี้เป็นอย่างไรในตารางกริด ให้ลองนึกภาพว่าคุณกำลังสร้างเลย์เอาต์ด้วย CSS grid ที่มีรายการที่วางอัตโนมัติซึ่งมีพื้นที่ที่โฟกัสได้ 12 พื้นที่
<div class="wrapper">
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
<a href="#">Four</a>
<a href="#">Five</a>
<a href="#">Six</a>
<a href="#">Seven</a>
<a href="#">Eight</a>
<a href="#">Nine</a>
<a href="#">Ten</a>
<a href="#">Eleven</a>
<a href="#">Twelve</a>
</div>
คุณต้องการให้บุตรหลานคนที่ 5 ใช้พื้นที่มากที่สุดที่ด้านบนสุด ตามด้วย บุตรหลานคนที่ 2 ที่อยู่ตรงกลางตารางกริด ส่วนรายการอื่นๆ ทั้งหมดจะวางในกริดโดยอัตโนมัติ ตามเทมเพลตคอลัมน์
.wrapper {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 100px;
}
.wrapper a:nth-child(2) {
grid-column: 3;
grid-row: 2 / 4;
}
.wrapper a:nth-child(5) {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
ลองไปยังส่วนต่างๆ เหล่านี้โดยใช้แป้น TAB เพื่อค้นหาองค์ประกอบที่โฟกัสได้ถัดไป และใช้แป้น TAB+SHIFT เพื่อค้นหาองค์ประกอบที่โฟกัสได้ก่อนหน้า โดยจะเรียงตาม รายการในแหล่งที่มาตามลำดับ 1 ถึง 12
หากต้องการแก้ไขปัญหานี้ ให้ตั้งค่าพร็อพเพอร์ตี้ reading-flow ดังนี้
.wrapper {
reading-flow: grid-rows;
}
ลำดับการโฟกัสตอนนี้คือ 5, 1, 3, 2, 4, 6, 7, 8, 9, 10, 11, 12 โดยจะเรียงตามลำดับภาพทีละแถว
หากต้องการให้ลำดับการอ่านเป็นไปตามลำดับคอลัมน์แทน คุณสามารถ
ใช้ค่าคีย์เวิร์ด grid-columns แทนได้ ลำดับโฟกัสจะกลายเป็น 5
6, 9, 7, 10, 1, 2, 11, 3, 4, 8, 12
.wrapper {
reading-flow: grid-columns;
}
นอกจากนี้ คุณยังลองใช้ grid-order ได้ด้วย ลำดับโฟกัสจะยังคงเป็น 1 ถึง 12
เนื่องจากไม่มีการตั้งค่าคำสั่งซื้อ CSS ในสินค้าใดๆ
คอนเทนเนอร์บล็อกที่ใช้ reading-order
พร็อพเพอร์ตี้ reading-order ช่วยให้คุณระบุได้ว่าควรเข้าชมรายการใดในโฟลว์การอ่าน
โดยจะลบล้างลำดับที่ตั้งค่าโดยพร็อพเพอร์ตี้ reading-flow โดยจะมีผลกับคอนเทนเนอร์โฟลว์การอ่านที่ถูกต้องเท่านั้น เมื่อพร็อพเพอร์ตี้ reading-flow
ไม่ใช่ normal
.wrapper {
display: block;
reading-flow: source-order;
}
.top {
reading-order: -1;
inset-inline-start: 50px;
inset-block-start: 50px;
}
คอนเทนเนอร์บล็อกต่อไปนี้มี 5 รายการ ไม่มีกฎเลย์เอาต์ ที่จัดเรียงองค์ประกอบใหม่จากลำดับแหล่งที่มา แต่มีรายการที่อยู่นอกโฟลว์ ซึ่งควรเข้าชมก่อน
<div class="wrapper">
<a href="#">Item 1</a>
<a href="#">Item 2</a>
<a href="#">Item 3</a>
<a href="#">Item 4</a>
<a class="top" href="#">Item 5</a>
</div>
การตั้งค่า reading-order ของรายการนี้เป็น -1 จะทำให้ลำดับโฟกัสไปที่รายการนี้ก่อน
ก่อนที่จะกลับไปใช้ลำดับแหล่งที่มาสำหรับรายการอื่นๆ ในโฟลว์การอ่าน
ดูตัวอย่างเพิ่มเติมได้ในเว็บไซต์ chrome.dev
การโต้ตอบกับ tabindex
ก่อนหน้านี้ นักพัฒนาซอฟต์แวร์ใช้แอตทริบิวต์ส่วนกลาง tabindex ของ HTML เพื่อทําให้องค์ประกอบ HTML โฟกัสได้และกําหนดลําดับที่เกี่ยวข้องสําหรับการไปยังส่วนต่างๆ ด้วยการโฟกัสตามลําดับ อย่างไรก็ตาม แอตทริบิวต์นี้มีข้อเสียหลายประการและข้อกังวลด้านการช่วยเหลือพิเศษ
ข้อกังวลหลักคือการนำทางด้วยโฟกัสที่เรียงตาม tabindex ซึ่งสร้างขึ้น
โดยใช้ tabindex ที่เป็นบวกจะไม่ได้รับการรับรู้โดย Accessibility Tree หากใช้ไม่ถูกต้อง คุณอาจได้ลำดับโฟกัสที่ไม่ราบรื่นซึ่งไม่ตรงกับ
ประสบการณ์การใช้งานในโปรแกรมอ่านหน้าจอ หากต้องการแก้ไข ให้ติดตามการจัดเรียงโดยใช้แอตทริบิวต์ HTML aria-owns
ในตัวอย่าง Flex ก่อนหน้า หากต้องการให้ได้ผลลัพธ์เช่นเดียวกับการใช้
reading-flow: flex-visual คุณอาจทำดังนี้
<div class="box" aria-owns="one three two">
<a href="#" tabindex="1" id="one">One</a>
<a href="#" tabindex="3" id="two">Two</a>
<a href="#" tabindex="2" id="three">Three</a>
</div>
แต่จะเกิดอะไรขึ้นหากองค์ประกอบอื่นนอกคอนเทนเนอร์มี tabindex=1 ด้วย
จากนั้นระบบจะเข้าชมองค์ประกอบทั้งหมดที่มี tabindex=1 พร้อมกัน ก่อนที่จะไปยัง
ค่า tabindex ที่เพิ่มขึ้นถัดไป การไปยังส่วนต่างๆ แบบต่อเนื่องที่ข้ามไปมานี้จะ
ส่งผลให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ไม่ดี ดังนั้น ผู้เชี่ยวชาญด้านการช่วยเหลือพิเศษจึงแนะนำให้หลีกเลี่ยง
tabindex ที่เป็นบวก เรา
พยายามแก้ไขปัญหานี้เมื่อออกแบบ reading-flow
คอนเทนเนอร์ที่มีการตั้งค่าพร็อพเพอร์ตี้ reading-flow จะกลายเป็นเจ้าของขอบเขตโฟกัส
ซึ่งหมายความว่าการนำทางด้วยโฟกัสตามลำดับจะกำหนดขอบเขตให้ไปที่องค์ประกอบทุกรายการ
ภายในคอนเทนเนอร์ก่อนที่จะย้ายไปยังองค์ประกอบที่โฟกัสได้ถัดไปในเอกสาร
เว็บ นอกจากนี้ ระบบจะจัดเรียงองค์ประกอบย่อยโดยตรงโดยใช้พร็อพเพอร์ตี้ reading-flow
และจะละเว้น tabindex ที่เป็นค่าบวกเพื่อวัตถุประสงค์ในการจัดเรียง คุณยังคง
ตั้งค่า tabindex เชิงบวกในองค์ประกอบย่อยของรายการโฟลว์การอ่านได้
โปรดทราบว่าองค์ประกอบที่มี display: contents ซึ่งรับค่าพร็อพเพอร์ตี้ reading-flow
จากเลย์เอาต์ระดับบนสุดจะเป็นคอนเทนเนอร์ลำดับการอ่านที่ถูกต้องด้วย โปรด
คำนึงถึงเรื่องนี้เมื่อออกแบบเว็บไซต์ อ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ใน
คำขอความคิดเห็นเกี่ยวกับ reading-flow และ display: contents
โปรดแจ้งให้เราทราบ
ลองใช้ตัวอย่างในโพสต์นี้และในreading-flowตัวอย่างใน chrome.dev แล้วใช้พร็อพเพอร์ตี้ CSS
เหล่านี้ในเว็บไซต์ของคุณ หากมีความคิดเห็น โปรดแจ้งเป็นปัญหาในที่เก็บ GitHub ของกลุ่มทำงาน CSS หากมีข้อเสนอแนะเกี่ยวกับลักษณะการทำงานของ tabindex และการกำหนดขอบเขตโฟกัสโดยเฉพาะ โปรดแจ้งเป็นปัญหาในที่เก็บ HTML WHATNOT GitHub เราอยากทราบความคิดเห็นของคุณเกี่ยวกับ
ฟีเจอร์นี้