เผยแพร่เมื่อวันที่ 6 พ.ย. 2024
ตั้งแต่ Chrome 131 คุณจะมีตัวเลือกเพิ่มเติมในการจัดรูปแบบโครงสร้างขององค์ประกอบ <details>
และ <summary>
ตอนนี้คุณใช้องค์ประกอบเหล่านี้เมื่อสร้างวิดเจ็ตการเปิดเผยหรือวิดเจ็ตแบบแอคคอร์เดียนได้แล้ว
โดยเฉพาะอย่างยิ่ง การเปลี่ยนแปลงที่เปิดตัวใน Chrome 131 จะช่วยให้ใช้พร็อพเพอร์ตี้ display
ในองค์ประกอบเหล่านี้ได้ และเพิ่มองค์ประกอบจำลอง ::details-content
เพื่อจัดสไตล์ส่วนที่ขยายและยุบ
การรองรับเบราว์เซอร์
การตั้งค่า display
ในองค์ประกอบ <details>
ก่อนหน้านี้คุณไม่สามารถเปลี่ยนประเภทการแสดงผลขององค์ประกอบ <details>
ได้ ตอนนี้เราได้ผ่อนปรนข้อจำกัดนี้แล้ว ซึ่งช่วยให้คุณใช้เลย์เอาต์แบบตารางกริดหรือเลย์เอาต์แบบยืดหยุ่นในองค์ประกอบ <details>
ได้ เป็นต้น
ในตัวอย่างต่อไปนี้ 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", "blockเครื่องหมายคำพูด", "center", "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "main", "summary", "nav", "olsearch", "summary", "nav", "olsearch"
หากกององค์ประกอบที่เปิดอยู่มีองค์ประกอบ 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
ในเบราว์เซอร์ ระบบจะใช้องค์ประกอบ <details>
โดยใช้ Shadow DOM โดยมี <slot>
1 รายการสำหรับข้อมูลสรุป (ซึ่งมีองค์ประกอบย่อยข้อมูลสรุปเริ่มต้น) และ <slot>
1 รายการสำหรับเนื้อหาที่เหลือทั้งหมด ซึ่งหมายถึงองค์ประกอบย่อยทั้งหมดขององค์ประกอบ <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>
นอกจากการใช้ประเภทการแสดงผลเพิ่มเติมใน <details>
แล้ว ตอนนี้คุณยังกําหนดเป้าหมายช่องเนื้อหาได้โดยใช้องค์ประกอบจำลอง ::details-content
คุณสามารถใช้สิ่งเทียมนี้เพื่อจัดรูปแบบคอนเทนเนอร์ที่ห่อหุ้มเนื้อหาขององค์ประกอบ <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 จะเปลี่ยนแปลงระหว่างสถานะ "ไม่ได้เปิด" และ "เปิด" ตามที่ระบุไว้ในสไตล์ชีต 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
แอคคอร์เดียนของ UIKit
สาธิต
กำลังบันทึก
ตัวอย่างนี้สร้างขึ้นหลังจาก Accordion ของ UIKit โค้ดนั้นเหมือนกันกับหีบเพลง UI ของ Material ที่ได้แชร์ไปก่อนหน้านี้
วิดเจ็ตการเปิดเผยข้อมูลแบบเปิดบางส่วน
สาธิต
กำลังบันทึก
การสาธิตนี้แสดงวิดเจ็ตการเปิดเผยที่เปิดอยู่บางส่วนซึ่งมีเนื้อหาปรากฏบนหน้าจออยู่แล้ว 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
จะเคลื่อนไหว