เผยแพร่: 6 พ.ย. 2024
ตั้งแต่ Chrome 131 เป็นต้นไป คุณจะมีตัวเลือกเพิ่มเติมในการจัดรูปแบบโครงสร้างขององค์ประกอบ <details>
และ <summary>
ตอนนี้คุณใช้องค์ประกอบเหล่านี้ได้แล้วเมื่อสร้างวิดเจ็ตการเปิดเผยข้อมูลหรือวิดเจ็ตแบบออร์แกน
โดยเฉพาะอย่างยิ่ง การเปลี่ยนแปลงที่เปิดตัวใน Chrome 131 จะช่วยให้ใช้พร็อพเพอร์ตี้ display
ในองค์ประกอบเหล่านี้ได้ และเพิ่มองค์ประกอบเสมือน ::details-content
เพื่อจัดรูปแบบส่วนที่ขยายและยุบ
การตั้งค่า display
ในองค์ประกอบ <details>
ก่อนหน้านี้คุณไม่สามารถเปลี่ยนประเภทการแสดงผลขององค์ประกอบ <details>
ปัจจุบันข้อจำกัดนี้ได้รับการผ่อนปรนแล้ว ซึ่งช่วยให้คุณใช้เลย์เอาต์กริดหรือเลย์เอาต์ Flex ในองค์ประกอบ <details>
ได้ เป็นต้น
ในตัวอย่างต่อไปนี้ Exclusive Accordion ประกอบด้วยองค์ประกอบ <details>
หลายรายการที่วางอยู่ข้างกัน เมื่อขยายองค์ประกอบ <details>
รายการใดรายการหนึ่ง เนื้อหาขององค์ประกอบนั้นจะอยู่ข้าง <summary>
สาธิต
กำลังบันทึก
ซึ่งทำได้โดยใช้เลย์เอาต์ Flex ในองค์ประกอบ <details>
โดยใช้ CSS ต่อไปนี้
details {
display: flex;
flex-direction: row;
}
นอกจากนี้ ยังอนุญาตให้ใช้ค่าการแสดงผลอื่นๆ เช่น grid
ด้วย
หมายเหตุเกี่ยวกับการใช้ display: inline
ค่า display
ที่อาจทำให้เกิดผลลัพธ์ที่ไม่คาดคิดคือ inline
ไม่ใช่เพราะใช้ไม่ได้ แต่เป็นเพราะข้อจำกัดของโปรแกรมแยกวิเคราะห์ HTML
เมื่อวางองค์ประกอบ <details>
ไว้ภายในย่อหน้า จะบังคับให้ตัวแยกวิเคราะห์ HTML ปิดย่อหน้าที่เปิดอยู่ก่อน ตามที่กำหนดไว้ในส่วนที่ 13.2.6.4.7 ของมาตรฐาน HTML
แท็กเริ่มต้นที่มีชื่อแท็กเป็นหนึ่งในแท็กต่อไปนี้ "address", "article", "aside", "blockquote", "center", "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", "search", "section", "summary", "ul"
หากกลุ่มองค์ประกอบที่เปิดอยู่มีองค์ประกอบ p ในขอบเขตปุ่ม ให้ปิดองค์ประกอบ p แทรกองค์ประกอบ HTML สำหรับโทเค็น
ด้วยเหตุนี้ <details>
จะไหลไปในทิศทางของบล็อก ไม่ว่าคุณจะตั้งค่า display: inline
หรือไม่ก็ตาม
ตัวอย่างเช่น มาร์กอัปต่อไปนี้
<p>Hello <details>…</details> world</p>
หลังจากแยกวิเคราะห์แล้ว จะเป็นดังนี้
<p>Hello </p><details>…</details> world<p></p>
คุณสามารถดูได้ด้วยตัวเองในการสาธิตนี้โดยตรวจสอบมาร์กอัปที่แยกวิเคราะห์แล้วโดยใช้เครื่องมือสำหรับนักพัฒนาเว็บใน Chrome
โปรดทราบว่าการดำเนินการนี้ใช้ได้กับการซ้อน <details>
ภายใน <p>
เท่านั้น การใช้ display: inline
ใน <details>
ภายใน <div>
จะทำงานได้ดี
องค์ประกอบจำลอง ::details-content
ในเบราว์เซอร์ ระบบจะใช้ Shadow DOM เพื่อใช้งานองค์ประกอบ <details>
โดยมี <slot>
สำหรับสรุป (มีองค์ประกอบย่อยสรุปเริ่มต้น) และ <slot>
สำหรับเนื้อหาที่เหลือทั้งหมด ซึ่งหมายถึงองค์ประกอบย่อยทั้งหมดขององค์ประกอบ <details>
ยกเว้นองค์ประกอบ <summary>
<details>
↳ #shadow-root (user-agent)
<slot id="details-summary">
<summary>Details</summary>
<!-- The summary goes here -->
</slot>
<slot id="details-content">
<!-- All content goes here -->
</slot>
</details>
นอกเหนือจากการใช้โฆษณา Display ประเภทอื่นๆ ใน <details>
แล้ว ตอนนี้คุณยังกำหนดเป้าหมายช่องเนื้อหาได้โดยใช้::details-content
องค์ประกอบเสมือน คุณสามารถใช้ Pseudo นี้เพื่อจัดรูปแบบคอนเทนเนอร์ที่ครอบเนื้อหาขององค์ประกอบ <details>
details::details-content {
border: 5px dashed hotpink;
}
หากต้องการใช้รูปแบบที่ตั้งค่าไว้เฉพาะเมื่อองค์ประกอบ <details>
อยู่ในสถานะเปิด ให้เพิ่มตัวเลือก [open]
ไว้ข้างหน้า
[open]::details-content {
border: 5px dashed hotpink;
}
ขอแนะนำให้ใช้สไตล์กับองค์ประกอบเสมือน ::details-content
เท่านั้นเมื่อองค์ประกอบ <details>
อยู่ในสถานะ [open]
สาธิต
กำลังบันทึก
ประเภท display
ของ ::details-content
ตั้งค่าเป็น block
ในสไตล์ชีต UA ในขณะที่ก่อนหน้านี้ตั้งค่าเป็น display: contents
การเปลี่ยนแปลงนี้อาจส่งผลเสียต่อคุณในบางกรณี เช่น เนื้อหาที่เปิดเผยซึ่งอิงตามheight: 100%
หากคุณพบปัญหานี้ คุณสามารถแก้ไขได้โดยตั้งค่าdisplay
กลับเป็นcontents
ดังนี้ details[open]::details-content { display: contents; }
การทำให้องค์ประกอบจำลอง ::details-content
เคลื่อนไหว
คุณสามารถทำให้เนื้อหาขององค์ประกอบ <details>
เคลื่อนไหวขณะขยายได้ ในตัวอย่างต่อไปนี้ ความกว้างจะเคลื่อนไหวจาก 0px
เป็น 300px
::details-content {
transition: width 0.5s ease, content-visibility 0.5s ease allow-discrete;
width: 0;
}
[open]::details-content {
width: 300px;
}
นอกเหนือจากการเปลี่ยน width
แล้ว พร็อพเพอร์ตี้ content-visibility
ก็ต้องเปลี่ยนด้วย เนื่องจากค่าจะเปลี่ยนแปลงระหว่างสถานะที่ยังไม่ได้เปิดและสถานะที่เปิดแล้ว ตามที่กำหนดไว้ในชีตสไตล์ User-Agent เนื่องจากพร็อพเพอร์ตี้นั้นเป็นพร็อพเพอร์ตี้ที่เคลื่อนไหวได้แบบไม่ต่อเนื่อง คุณจึงต้องใช้คีย์เวิร์ด allow-discrete
เพื่อให้ทำงานได้
เมื่อเพิ่มลงในเดโม Accordion แบบพิเศษที่แชร์ไว้ก่อนหน้านี้ ผลลัพธ์จะเป็นดังนี้
สาธิต
กำลังบันทึก
height
ยังสามารถทำเป็นภาพเคลื่อนไหวได้ด้วย หากต้องการเปลี่ยนภาพเคลื่อนไหวเป็น height: auto
คุณต้องใช้ interpolate-size
หรือ calc-size()
นอกจากนี้ ให้ใช้ overflow: clip
กับเนื้อหาเพื่อป้องกันไม่ให้เนื้อหาล้นออกมาจาก ::details-content
::details-content {
transition: height 0.5s ease, content-visibility 0.5s ease allow-discrete;
height: 0;
overflow: clip;
}
/* Browser supports interpolate-size */
@supports (interpolate-size: allow-keywords) {
:root {
interpolate-size: allow-keywords;
}
[open]::details-content {
height: auto;
}
}
/* Fallback for browsers with no interpolate-size support */
@supports not (interpolate-size: allow-keywords) {
[open]::details-content {
height: 150px;
overflow-y: scroll; /* In case the contents should be taller than 150px */
}
}
คุณดูโค้ดที่ใช้งานได้ในเดโมต่อไปนี้ ซึ่งได้แรงบันดาลใจจาก Accordion ของ Material UI เนื้อหาขององค์ประกอบ <details>
แต่ละรายการจะเคลื่อนไหวอย่างสวยงาม
สาธิต
กำลังบันทึก
ในเบราว์เซอร์ที่ไม่รองรับ ::details-content
คอมโพเนนต์จะยังคงทำงานได้ดี สิ่งเดียวที่ผู้เข้าชมจะไม่เห็นคือภาพเคลื่อนไหว
การตรวจหาฟีเจอร์
หากต้องการตรวจหาการรองรับ::details-content
เทียมใน CSS ให้ใช้ข้อมูลโค้ดต่อไปนี้
@supports selector(::details-content) {
…
}
นอกจากนี้ คุณยังใช้การตรวจหานี้เป็นการตรวจสอบที่บ่งบอกถึงปัญหาเพื่อดูว่าเบราว์เซอร์ที่ผู้เข้าชมใช้รองรับค่าการแสดงผลเพิ่มเติมหรือไม่
ข้อควรพิจารณาเกี่ยวกับการช่วยเหลือพิเศษ
การเปิดตัวองค์ประกอบเสมือน ::details-content
และความสามารถในการเปลี่ยนประเภทการแสดงผลไม่มีผลต่อการช่วยเหลือพิเศษขององค์ประกอบ <details>
เช่นเดียวกับก่อนหน้านี้ อย่างน้อยในเบราว์เซอร์ที่ใช้ Chromium และตามมาตรฐาน HTML องค์ประกอบ <details>
จะค้นหาได้และขยายโดยอัตโนมัติเมื่อเบราว์เซอร์พยายามเลื่อนไปยังเนื้อหาที่ซ่อนอยู่เพื่อตอบสนองต่อการค้นหาในหน้า, ScrollToTextFragment และการนำทางไปยังส่วนย่อยขององค์ประกอบ ซึ่งจะไม่เปลี่ยนแปลง
อย่างไรก็ตาม ก่อนใช้ Accordion แบบพิเศษ ให้พิจารณาว่าจะเป็นประโยชน์หรือเป็นอันตรายต่อผู้ใช้ แม้ว่าการใช้ Accordion แบบพิเศษจะช่วยลดพื้นที่ภาพที่เนื้อหาใช้ แต่ผู้ใช้อาจต้องเปิดหลายรายการเพื่อดูข้อมูลทั้งหมด ซึ่งอาจทำให้ผู้ใช้ที่ต้องการดูหลายรายการพร้อมกันรู้สึกหงุดหงิด
แล้วการจัดรูปแบบเครื่องหมายล่ะ
ปัจจุบันการจัดรูปแบบเครื่องหมายรายการใช้ร่วมกันไม่ได้เนื่องจากมี 2 แนวทางที่แตกต่างกัน โดยแนวทางหนึ่งใช้โดย Gecko และ Chromium (ปัจจุบัน) และอีกแนวทางหนึ่งใช้โดย WebKit (ซึ่งก่อนหน้านี้แชร์กับ Chromium)
เมื่อฟีเจอร์นี้ทำงานร่วมกันได้แล้ว เราจะช่วยให้คุณควบคุมวิธีจัดรูปแบบเครื่องหมายได้ดียิ่งขึ้น
การสาธิตเพิ่มเติม
สุดท้ายนี้ เรามีวิดีโอสาธิตเพิ่มเติมให้คุณดู ทั้งหมดใช้ ::details-content
Accordion ของ UIKit
สาธิต
กำลังบันทึก
การสาธิตนี้สร้างขึ้นตาม UIKit Accordion โค้ดนี้แทบจะเหมือนกับ Accordion ของ Material UI ที่แชร์ก่อนหน้านี้
วิดเจ็ตการเปิดเผยข้อมูลที่เปิดบางส่วน
สาธิต
กำลังบันทึก
การสาธิตนี้แสดงวิดเจ็ตการเปิดเผยข้อมูลที่เปิดอยู่บางส่วนซึ่งเนื้อหาปรากฏบนหน้าจออยู่แล้ว โดย content-visibility
จะตั้งค่าเป็น visible
เสมอ height
จะเคลื่อนไหวcalc-size()
เนื่องจากมีการคำนวณ
::details-content {
content-visibility: visible; /* Make it always visible */
transition: height 0.5s ease;
height: 150px;
overflow: clip;
}
[open]::details-content {
height: calc-size(auto, size + 0.5rem); /* calc-size because we need to add a length */
}
เพื่อความสะดวกในการจัดรูปแบบ ระบบจะห่อหุ้มเนื้อหาในองค์ประกอบ div ของ Wrapper องค์ประกอบ div ของ Wrapper จะได้รับรูปแบบเลย์เอาต์ เช่น padding
และระบบจะเคลื่อนไหวองค์ประกอบเสมือน ::details-content