เผยแพร่: 6 พ.ย. 2024
ตั้งแต่ Chrome 131 คุณจะมีตัวเลือกเพิ่มเติมในการจัดรูปแบบโครงสร้างขององค์ประกอบ <details>
และ <summary>
ตอนนี้คุณใช้องค์ประกอบเหล่านี้เมื่อสร้างวิดเจ็ตการเปิดเผยหรือวิดเจ็ตแบบแอคคอร์เดียนได้แล้ว
โดยเฉพาะอย่างยิ่ง การเปลี่ยนแปลงที่เปิดตัวใน Chrome 131 จะช่วยให้ใช้พร็อพเพอร์ตี้ display
ในองค์ประกอบเหล่านี้ได้ และเพิ่มองค์ประกอบจำลอง ::details-content
เพื่อจัดสไตล์ส่วนที่ขยายและยุบ
การรองรับเบราว์เซอร์
การตั้งค่า display
ในองค์ประกอบ <details>
ก่อนหน้านี้คุณไม่สามารถเปลี่ยนประเภทการแสดงผลขององค์ประกอบ <details>
ได้ ตอนนี้เราผ่อนปรนข้อจำกัดนี้แล้ว ซึ่งจะช่วยให้คุณใช้เลย์เอาต์ตารางกริดหรือ Flex ในองค์ประกอบ <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", "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
ในเบราว์เซอร์ ระบบจะใช้องค์ประกอบ <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 โค้ดนี้แทบจะเหมือนกับ 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
จำลองภาพเคลื่อนไหว