ชื่อ CSS ที่ผู้เขียนกำหนดและ Shadow DOM: เป็นไปตามข้อกำหนดและในทางปฏิบัติ

ชื่อ CSS ที่กำหนดโดยผู้เขียนและ Shadow DOM ควรทำงานร่วมกัน อย่างไรก็ตาม เบราว์เซอร์ไม่สอดคล้องกับข้อกำหนด ซึ่งบางครั้งอาจมี อื่นๆ และชื่อ 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 พร็อพเพอร์ตี้ที่กำหนดเองใดๆ
ดูการเปลี่ยนหน้า view-transition-name
view-transition-class
::view-transition-group()
จุดยืนของจุดยึด anchor-name position-anchor
ภาพเคลื่อนไหวแบบเลื่อน animation-timeline view-timeline-name
scroll-timeline-name
รูปแบบตัวนับ @counter-style
Counter-reset
counter-set
counter-increment
list-style
การค้นหาคอนเทนเนอร์ container-name @container
ตัวแปร CSS --something var(--something)
หน้าเว็บ @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 อื่นๆ ตรงที่พร็อพเพอร์ตี้ CSS ไม่ห่อหุ้มด้วย Shadow DOM แต่เป็นวิธีการทั่วไปในการส่งผ่านพารามิเตอร์ผ่านเงาที่แตกต่างกัน ต้นไม้ สิ่งนี้จะทำให้ ตัวบ่งชี้ @property พิเศษ: ระบบควรทำงานเหมือนกับการประกาศประเภทเอกสารทั่วโลก กำหนดการกระทำของทรัพย์สินที่มีชื่อเรียกหนึ่งๆ เนื่องจากที่พักต้องตรงกัน ท่ามกลางเงาต้นไม้ การประกาศอสังหาริมทรัพย์ที่ไม่สอดคล้องกันจะทำให้เกิดข้อมูลที่ไม่คาดคิด ดังนั้น ระบบจึงระบุการประกาศ @property ให้แยกและแก้ปัญหา ตามลำดับเอกสาร

วิธีที่กฎควรทำงานร่วมกับ ::part

ส่วนของการให้แสงเงา แสดงองค์ประกอบภายในต้นไม้เงาต้นไม้หลัก การดำเนินการดังกล่าว แผนผังระดับบนสุดสามารถเข้าถึงองค์ประกอบนั้น และยังจัดรูปแบบโดยใช้ ::part

เนื่องจาก ::part อนุญาตให้ขอบเขตแผนผังต้นไม้ 2 ขอบเขตจัดสไตล์องค์ประกอบเดียวกันได้ ดังนี้ ระบุลำดับแบบ Cascade ดังต่อไปนี้

  1. ขั้นแรก ให้ตรวจสอบรูปแบบในบริบทของเงา นี่คือ "ค่าเริ่มต้น" ของส่วนนั้นด้วย
  2. จากนั้นใช้รูปแบบภายนอกตามที่ระบุไว้ใน ::part นี่คือ "กำหนดเอง" ของส่วนนั้นด้วย
  3. จากนั้นจึงใช้รูปแบบภายในที่กำหนดร่วมกับ !important ซึ่งทำให้องค์ประกอบที่กำหนดเองสามารถประกาศว่า คุณสมบัติบางอย่าง ของ ไม่สามารถปรับแต่งโดย ::part

ซึ่งหมายความว่าชื่อจากภายใน Shadow DOM ไม่สามารถอ้างอิงจาก ::part เนื่องจาก ::part เป็นรูปแบบที่กำหนดขอบเขตระดับโฮสต์ ไม่ใช่ระดับแสงเงา สไตล์ เช่น

// 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;  
}

วิธีที่กฎควรทำงานกับรูปแบบแทรกในบรรทัด

ซึ่งต่างจาก ::part รูปแบบแทรกในบรรทัดที่มีแอตทริบิวต์ style หรือแอตทริบิวต์เหล่านั้น การตั้งค่ารูปแบบโดยใช้สคริปต์แบบเป็นโปรแกรมจะกำหนดขอบเขตไว้ที่ตำแหน่งที่องค์ประกอบ มีขอบเขตจำกัดอยู่ที่ เนื่องจากการนำรูปแบบไปใช้กับองค์ประกอบที่คุณต้องมีสิทธิ์เข้าถึง ที่จับสำหรับองค์ประกอบ และไปยังรากของเงานั้น

วิธีที่ชื่อ CSS และ Shadow DOM ทำงานร่วมกันในความเป็นจริง

แม้ว่ากฎก่อนหน้านี้จะมีการกำหนดไว้อย่างชัดเจนและสอดคล้องกัน แต่กฎเกณฑ์ปัจจุบัน และไม่ได้เป็นเช่นนั้นเสมอไป ในทางปฏิบัติ @property จะทำงานแตกต่างจากข้อมูลจำเพาะอย่างสอดคล้องกัน ในเบราว์เซอร์ และคุณลักษณะอื่นๆ ส่วนใหญ่มีข้อบกพร่องที่เปิดอยู่ ยังไม่ได้เปิดตัว จึงมีเวลาแก้ไข)

เพื่อทดสอบและสาธิตการทำงานของคุณลักษณะเหล่านี้ในทางปฏิบัติ เราจึงสร้าง หน้าต่อไปนี้: https://css-names-in-the-shadow.glitch.me/. หน้าเว็บนี้มี iframe จำนวนมาก แต่ละ iframe มุ่งเน้นที่คุณลักษณะใดคุณลักษณะหนึ่งและทดสอบ สถานการณ์ต่างๆ

  • การอ้างอิงภายนอกไปยังชื่อด้านนอก: ไม่มี 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 พบประสบการณ์ที่ไม่สอดคล้องกันและ Buggy ฟีเจอร์ไม่มีที่ตรวจสอบที่นี่ทำงานสม่ำเสมอ และเป็นไปตามข้อกำหนด ข่าวดีก็คือ เดลต้าเพื่อสร้างประสบการณ์ที่สม่ำเสมอนั้นเป็น รายการข้อบกพร่องและปัญหาข้อมูลจำเพาะ มาแก้ปัญหานี้กัน ในระหว่างนี้ ภาพรวมนี้น่าจะช่วยคุณได้หากคุณกำลังประสบปัญหาเกี่ยวกับ ความไม่สอดคล้องกันที่อธิบายไว้ในบทความนี้