ชื่อ CSS ที่ผู้ใช้กำหนดและ Shadow DOM ควรทำงานร่วมกัน อย่างไรก็ตาม เบราว์เซอร์ไม่สอดคล้องกับข้อกำหนด และบางครั้งก็ใช้ชื่อ CSS ที่ไม่สอดคล้องกัน และชื่อ CSS แต่ละชื่อก็มีความไม่สอดคล้องกันเล็กน้อย
บทความนี้จะบันทึกสถานะปัจจุบันของลักษณะการทํางานของชื่อ CSS ที่กําหนดโดยผู้เขียนในขอบเขตเงา โดยหวังว่าบทความนี้จะใช้เป็นแนวทางในการปรับปรุงความสามารถในการทำงานร่วมกันในอนาคตอันใกล้
ชื่อ CSS ที่ผู้เขียนกำหนดคืออะไร
ชื่อ CSS ที่นักเขียนกำหนดเป็นกลไกไวยากรณ์ CSS ที่ค่อนข้างเก่า ซึ่งเดิมทีมีไว้สำหรับกฎ @keyframes
ซึ่งกำหนด <keyframe-name>
เป็นตัวระบุที่กำหนดเองหรือสตริง แนวคิดนี้มีไว้เพื่อประกาศบางอย่างในส่วนหนึ่งของสไตล์ชีต แล้วอ้างอิงในส่วนอื่น
/* "fade-in" is a CSS name, representing a set of keyframes */
@keyframes fade-in {
from { opacity: 0 };
to { opacity: 1 }
}
.card {
/* "fade-in" is a reference to the above keyframes */
animation-name: fade-in;
}
ฟีเจอร์อื่นๆ ของ CSS ที่ใช้ชื่อ CSS ได้แก่ แบบอักษร การประกาศพร็อพเพอร์ตี้ การค้นหาคอนเทนเนอร์ และการเปลี่ยนมุมมองล่าสุด การกำหนดตำแหน่ง Anchor และภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน ตารางต่อไปนี้ไม่ได้ครอบคลุมทั้งหมด แต่มีชื่อของรายการที่ Chrome ตรวจสอบสถานะ
ฟีเจอร์ | การประกาศชื่อ | การอ้างอิงชื่อ |
---|---|---|
คีย์เฟรม | @keyframes |
animation-name |
แบบอักษร | @font-face { }
@font-palette-values |
font-family
font-palette |
การประกาศพร็อพเพอร์ตี้ | @property การประกาศพร็อพเพอร์ตี้ที่กำหนดเองซึ่งไม่ได้ลงทะเบียน |
var() |
ดูการเปลี่ยน | view-transition-name
view-transition-class |
องค์ประกอบจำลอง ::view-transition-* รายการ |
ตำแหน่งของ Anchor | anchor-name |
position-anchor |
ภาพเคลื่อนไหวแบบเลื่อน | view-timeline-name
scroll-timeline-name |
animation-timeline |
รูปแบบรายการ | @counter-style |
list-style |
ตัวนับ | counter-reset
counter-set
counter-increment |
|
การค้นหาคอนเทนเนอร์ | container-name |
@container |
หน้าเว็บ | page |
@page |
จากที่เห็นในตาราง โดยทั่วไปชื่อ CSS จะมีการอ้างอิง CSS ที่สอดคล้องกัน เช่น animation-name
เป็นการอ้างอิงถึงชื่อ @keyframes
ชื่อ CSS แตกต่างจากชื่อที่กำหนดไว้ใน DOM เช่น แอตทริบิวต์และชื่อแท็ก เนื่องจากมีการประกาศแล้วอ้างอิงภายในบริบทของสไตล์ชีต
ความสัมพันธ์ของชื่อกับ Shadow DOM
แม้ว่าชื่อ CSS จะสร้างขึ้นเพื่อสร้างความสัมพันธ์ระหว่างส่วนต่างๆ ของเอกสารหรือสไตล์ชีต แต่ Shadow DOM สร้างขึ้นเพื่อทําตรงข้ามกัน โดยจะรวมความสัมพันธ์ไว้เพื่อไม่ให้ความสัมพันธ์ดังกล่าวแสดงในคอมโพเนนต์เว็บที่ควรจะเป็นเนมสเปซของตัวเอง
การนำชื่อ CSS และ Shadow DOM มารวมกันจะทำให้ประสบการณ์การคอมโพสิทคอมโพเนนต์เว็บมีความยืดหยุ่นมากพอ แต่ก็มีข้อจำกัดมากพอที่จะคงเสถียร
แนวคิดนี้ฟังดูดี ในทางปฏิบัติ เบราว์เซอร์ไม่สอดคล้องกับวิธีที่ชื่อ CSS ทำงานร่วมกับ Shadow DOM ทั้งระหว่างฟีเจอร์ในเบราว์เซอร์เดียวกัน ในเบราว์เซอร์ต่างๆ และระหว่างฟีเจอร์และข้อกำหนด
วิธีที่ชื่อและ Shadow DOM ควรทํางานร่วมกัน
ในการทำความเข้าใจปัญหานี้ คุณควรทำความเข้าใจว่า CSS ส่วนต่างๆ เหล่านี้ควรทำงานร่วมกันในเชิงทฤษฎีอย่างไร
กฎทั่วไป
กฎทั่วไปสำหรับลักษณะการทำงานของชื่อ CSS ในทรีเงาจะระบุไว้ในข้อกำหนดระดับ 1 เกี่ยวกับการกำหนดขอบเขต CSS สรุปคือ ชื่อ CSS จะเป็นแบบส่วนกลางภายในขอบเขตที่กำหนด ซึ่งหมายความว่าสามารถเข้าถึงได้จากต้นไม้เงาของรายการที่สืบทอด แต่เข้าถึงจากต้นไม้เงาของรายการพี่น้องหรือบรรพบุรุษไม่ได้ โปรดทราบว่าชื่อนี้แตกต่างจากชื่อในแพลตฟอร์มเว็บ เช่น รหัสองค์ประกอบ ซึ่งจะรวมอยู่ในขอบเขตต้นไม้เดียวกัน
ข้อยกเว้นสำหรับกฎ: @property
พร็อพเพอร์ตี้ CSS ไม่ได้อยู่ภายใน Shadow DOM ต่างจากชื่อ CSS อื่นๆ
แต่เป็นเพียงวิธีทั่วไปในการส่งพารามิเตอร์ไปยัง Shadow Tree ต่างๆ
สิ่งนี้ทำให้ข้อบ่งชี้ @property
พิเศษ: เนื่องจากควรทํางานเหมือนการประกาศประเภทระดับเอกสารที่กําหนดวิธีทํางานของพร็อพเพอร์ตี้ที่มีชื่อหนึ่งๆ เนื่องจากพร็อพเพอร์ตี้ต้องตรงกันทั่วทั้งต้นไม้เงา การประกาศพร็อพเพอร์ตี้ที่ไม่ตรงกันจะทำให้เกิดผลลัพธ์ที่ไม่คาดคิด ดังนั้นจึงมีการระบุการประกาศ @property
ให้ยุบและแก้ไขตามลําดับเอกสาร
วิธีที่กฎควรทํางานกับ ::part
ชิ้นส่วนเงาจะแสดงองค์ประกอบภายในต้นไม้เงาต่อต้นไม้หลัก ซึ่งจะทำให้ต้นไม้หลักเข้าถึงองค์ประกอบนั้นได้และจัดรูปแบบโดยใช้องค์ประกอบ ::part
ด้วย
เนื่องจาก ::part
อนุญาตให้สโคปต้นไม้ 2 รายการจัดสไตล์องค์ประกอบเดียวกันได้ ระบบจึงระบุลําดับการแสดงผลตามลำดับต่อไปนี้
- ก่อนอื่น ให้ตรวจสอบสไตล์ภายในบริบทเงา รูปแบบนี้เป็นรูปแบบ "เริ่มต้น" ของชิ้นส่วน
- จากนั้นใช้รูปแบบภายนอกตามที่ระบุไว้ใน
::part
นี่เป็นรูปแบบ ที่ "กำหนดเอง" ของชิ้นส่วน - จากนั้นใช้สไตล์ภายในที่กําหนดไว้ร่วมกับ
!important
การดำเนินการนี้ช่วยให้องค์ประกอบที่กำหนดเองประกาศว่า::part
ปรับแต่งพร็อพเพอร์ตี้บางอย่างของส่วนหนึ่งๆ ไม่ได้
ซึ่งหมายความว่าชื่อจากภายใน Shadow DOM จะอ้างอิงจาก ::part
ไม่ได้ เนื่องจาก ::part
เป็นสไตล์ระดับโฮสต์ ไม่ใช่สไตล์ระดับ Shadow เช่น
// inside the shadow DOM:
@keyframes fade-in {
from { opacity: 0}
}
// This shouldn't work!
// The host style shouldn't know the name "fade-in"
::part(slider) {
animation-name: fade-in;
}
วิธีที่กฎควรทำงานร่วมกับสไตล์ในบรรทัด
สไตล์อินไลน์ที่มีแอตทริบิวต์ style
หรือการตั้งค่ารูปแบบโดยใช้สคริปต์แบบเป็นโปรแกรมจะกำหนดขอบเขตไปยังบริเวณที่มีการกำหนดขอบเขตองค์ประกอบ ซึ่งต่างจาก ::part
เนื่องจากหากต้องการใช้สไตล์กับองค์ประกอบ คุณต้องมีสิทธิ์เข้าถึงแฮนเดิลองค์ประกอบ และรูทเงา
วิธีที่ชื่อ CSS และ Shadow DOM ทำงานร่วมกันในความเป็นจริง
แม้ว่ากฎข้างต้นจะชัดเจนและสอดคล้องกัน แต่การใช้งานในปัจจุบันอาจไม่เป็นไปตามกฎดังกล่าวเสมอไป
ในทางปฏิบัติ @property
ทำงานแตกต่างจากข้อกำหนดในลักษณะที่สอดคล้องกันในเบราว์เซอร์ต่างๆ และฟีเจอร์อื่นๆ ส่วนใหญ่ยังมีข้อบกพร่องอยู่ (บางฟีเจอร์ยังไม่ได้เปิดตัว จึงมีเวลาแก้ไข)
เราได้สร้างหน้าต่อไปนี้เพื่อทดสอบและสาธิตวิธีการทำงานของฟีเจอร์เหล่านี้จริง https://css-names-in-the-shadow.glitch.me/ หน้านี้มี iframe หลายรายการ โดยแต่ละ iframe จะมุ่งเน้นฟีเจอร์ใดฟีเจอร์หนึ่งและทำการทดสอบ 6 สถานการณ์ต่อไปนี้
- การอ้างอิงภายนอกถึงชื่อภายนอก: ไม่มี Shadow DOM ที่เกี่ยวข้อง วิธีนี้น่าจะใช้ได้
- การอ้างอิงภายนอกไปยังชื่อภายใน: ไม่ควรทำงานเนื่องจากหมายความว่าชื่อที่กำหนดไว้ในบริบทเงาหลุด
- การอ้างอิงภายในถึงชื่อภายนอก: การดำเนินการนี้ควรใช้งานได้ เนื่องจากรูทเงาจะรับค่าชื่อระดับต้นไม้
- การอ้างอิงภายในถึงชื่อภายใน: การดำเนินการนี้ควรใช้งานได้ เนื่องจากทั้งชื่อการอ้างอิงอยู่ในขอบเขตเดียวกัน
::part
อ้างอิงถึงชื่อด้านนอก: ควรใช้งานได้ เนื่องจากทั้ง::part
และชื่อได้รับการประกาศไว้ในขอบเขตเดียวกัน::part
การอ้างอิงชื่อภายใน: การดำเนินการนี้ไม่ควรทำงานเนื่องจากขอบเขตภายนอกไม่ควรได้รับข้อมูลเกี่ยวกับชื่อที่ประกาศภายใน Shadow DOM
@keyframes
ตามที่ระบุไว้ในข้อกำหนด คุณควรจะอ้างอิงชื่อคีย์เฟรมจากภายในรากเงาได้ ตราบใดที่กฎ at @keyframes
อยู่ในขอบเขตระดับบน ในทางปฏิบัติจะไม่มีเบราว์เซอร์ใดใช้ลักษณะการทำงานนี้ และจะอ้างอิงคำจำกัดความคีย์เฟรมได้ในขอบเขตที่มีการกำหนดไว้เท่านั้น ดูปัญหา 10540
@property
ตามที่ระบุไว้ในข้อกำหนด การประกาศ @property
ทั้งหมดจะรวมอยู่ในขอบเขตของเอกสาร แต่ในปัจจุบัน คุณประกาศ @property
ได้เฉพาะในสโกปเอกสารในเบราว์เซอร์ทุกประเภท และระบบจะไม่สนใจการประกาศ @property
ภายในรูทเงา
ดูปัญหา 10541
ข้อบกพร่องเฉพาะเบราว์เซอร์
ฟีเจอร์อื่นๆ แสดงลักษณะการทำงานที่ไม่สอดคล้องกันในเบราว์เซอร์ต่างๆ
@font-face
จะยุบเป็นขอบเขตรูทใน Safari- Chromium ไม่อนุญาตให้รับค่ากฎ
anchor-name
ในรูทเงา scroll-timeline-name
และview-timeline-name
ไม่ได้กําหนดขอบเขตอย่างถูกต้องใน::part
(และใน Chromium ด้วย)- ไม่มีเบราว์เซอร์ใดอนุญาตให้ประกาศ
@font-palette-values
ในรูทเงา view-transition-class
สามารถกําหนดภายในรูทเงา (ทรานซิชันอยู่นอกรูทเงา)- Firefox อนุญาตให้
::part
เข้าถึงชื่อเงาภายใน (คำค้นหาคอนเทนเนอร์ คีย์เฟรม) - Firefox และ Safari ไม่สนใจ
@counter-style
ในรูทเงา
โปรดทราบว่า counter-reset
, counter-set
, counter-increment
มีกฎที่ต่างกันเล็กน้อยเนื่องจากเป็นชื่อที่ระบุโดยนัย และการประกาศพร็อพเพอร์ตี้ CSS มีชุดกฎที่กำหนดไว้และผ่านการทดสอบมาอย่างดี
บทสรุป
ข่าวร้ายคือเมื่อตรวจสอบภาพรวมสถานะการทำงานร่วมกันในปัจจุบันเกี่ยวกับชื่อ CSS และ Shadow DOM พบว่าประสบการณ์การใช้งานไม่สอดคล้องกันและมีข้อบกพร่อง ไม่มีฟีเจอร์ใดที่เราตรวจสอบที่นี่ทำงานอย่างสอดคล้องกันในเบราว์เซอร์ต่างๆ และเป็นไปตามข้อกำหนด ข่าวดีคือความแตกต่างที่จะทำให้ประสบการณ์การใช้งานสอดคล้องกันนั้นมีจำนวนจำกัด นั่นคือรายการข้อบกพร่องและปัญหาเกี่ยวกับข้อกำหนด มาแก้ปัญหานี้กัน ในระหว่างนี้ เราหวังว่าภาพรวมนี้จะช่วยคุณได้หากพบปัญหาความไม่สอดคล้องตามที่อธิบายไว้ในบทความนี้