Nama CSS yang ditentukan penulis dan shadow DOM seharusnya berfungsi bersama. Namun, browser tidak konsisten dengan spesifikasi, terkadang dengan browser lain, dan setiap nama CSS tidak konsisten dengan cara yang sedikit berbeda.
Artikel ini mendokumentasikan status saat ini tentang perilaku nama CSS yang ditentukan penulis di seluruh cakupan bayangan, dengan harapan dapat berfungsi sebagai panduan untuk meningkatkan interoperabilitas dalam waktu dekat.
Apa yang dimaksud dengan nama CSS yang ditentukan penulis?
Nama CSS yang ditentukan penulis adalah mekanisme sintaksis CSS yang relatif lama, yang awalnya
diperkenalkan untuk aturan @keyframes
, yang menentukan <keyframe-name>
sebagai
identitas kustom atau string. Tujuan konsep ini adalah untuk mendeklarasikan
sesuatu di satu bagian stylesheet, dan merujuknya di bagian lain.
/* "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;
}
Fitur CSS lainnya yang menggunakan nama CSS adalah font, deklarasi properti, kueri penampung, dan transisi tampilan, posisi anchor, dan animasi yang didorong scroll yang lebih baru. Tabel non-komprehensif berikut menyertakan nama yang statusnya diperiksa oleh Chrome.
Fitur | Pernyataan nama | Referensi nama |
---|---|---|
Frame utama | @keyframes |
animation-name |
Font | @font-face { }
@font-palette-values |
font-family
font-palette |
Deklarasi Properti | @property Deklarasi properti kustom yang tidak terdaftar |
var() |
Melihat transisi | view-transition-name
view-transition-class |
::view-transition-* elemen pseudo |
Penempatan Anchor | anchor-name |
position-anchor |
Animasi berbasis scroll | view-timeline-name
scroll-timeline-name |
animation-timeline |
Gaya daftar | @counter-style |
list-style |
Penghitung | counter-reset
counter-set
counter-increment |
|
Kueri penampung | container-name |
@container |
Halaman | page |
@page |
Seperti yang dapat Anda lihat dalam tabel, nama CSS biasanya memiliki referensi CSS yang sesuai. Misalnya, animation-name
adalah referensi ke nama
@keyframes
. Nama CSS berbeda dengan nama yang ditentukan di DOM, seperti atribut
dan nama tag, karena dideklarasikan, lalu dirujuk dalam konteks
stylesheet.
Hubungan nama dengan shadow DOM
Meskipun nama CSS dibuat untuk membuat hubungan antara berbagai bagian dokumen atau stylesheet, Shadow DOM dibuat untuk melakukan hal sebaliknya. Class ini mengenkapsulasi hubungan sehingga tidak bocor di seluruh komponen web yang seharusnya memiliki namespace-nya sendiri.
Dengan menggabungkan nama CSS dan shadow DOM, pengalaman dalam menyusun komponen web akan terasa cukup ekspresif agar fleksibel, tetapi cukup dibatasi agar stabil.
Hal ini bagus secara teori. Dalam praktiknya, browser tidak konsisten dalam cara nama CSS beroperasi dengan shadow DOM, baik di antara fitur dalam browser yang sama, di seluruh browser, maupun di antara fitur dan spesifikasi.
Cara nama dan shadow DOM harus bekerja sama
Untuk memahami masalahnya, sebaiknya pahami cara kerja bagian-bagian CSS ini secara teori.
Aturan umum
Aturan umum tentang perilaku nama CSS di seluruh hierarki bayangan ditentukan dalam spesifikasi CSS Scoping Level 1. Untuk meringkas: nama CSS bersifat global di dalam cakupan tempatnya ditentukan, yang berarti nama tersebut dapat diakses dari hierarki turunan, tetapi tidak dari hierarki saudara atau hierarki induk. Perhatikan bahwa ini tidak seperti nama di platform web seperti ID elemen, yang dienkapsulasi dalam cakupan hierarki yang sama.
Pengecualian untuk aturan: @property
Tidak seperti nama CSS lainnya, properti CSS tidak dienkapsulasi oleh shadow DOM.
Sebaliknya, ini adalah cara umum untuk meneruskan parameter di berbagai hierarki
bayangan.
Hal ini membuat
deskripsi @property
khusus: deskripsi ini seharusnya berperilaku seperti deklarasi jenis global dokumen yang
menentukan cara kerja properti bernama tertentu. Karena properti harus cocok
di seluruh hierarki bayangan, ketidakcocokan deklarasi properti akan menghasilkan hasil
yang tidak terduga, sehingga deklarasi @property
ditentukan untuk diratakan dan diselesaikan
sesuai dengan urutan dokumen.
Cara kerja aturan dengan ::part
Bagian bayangan
mengekspos elemen di dalam hierarki bayangan ke hierarki induknya. Dengan demikian, hierarki induk dapat mengakses elemen tersebut dan juga menata gayanya menggunakan elemen
::part
.
Karena ::part
memungkinkan dua cakupan hierarki menata gaya elemen yang sama, urutan cascade
berikut ditentukan:
- Pertama, periksa gaya di dalam konteks bayangan. Ini adalah gaya "default" bagian.
- Kemudian, terapkan gaya eksternal seperti yang ditentukan di
::part
. Ini adalah gaya "kustom" bagian. - Kemudian, terapkan gaya internal apa pun yang ditentukan bersama dengan
!important
. Hal ini memungkinkan elemen kustom mendeklarasikan bahwa properti tertentu dari bagian tertentu tidak dapat disesuaikan oleh::part
.
Artinya, nama dari dalam shadow DOM tidak dapat direferensikan dari
::part
, karena ::part
adalah gaya cakupan host, bukan gaya cakupan
bayangan. Contoh:
// 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;
}
Cara kerja aturan dengan gaya inline
Tidak seperti ::part
, gaya inline dengan atribut style
, atau gaya yang
menetapkan gaya secara terprogram menggunakan skrip, dicakup ke tempat elemen
dicakup. Hal ini karena untuk menerapkan gaya ke elemen, Anda memerlukan akses ke
handle elemen, dan dengan demikian ke root bayangan itu sendiri.
Cara nama CSS dan DOM bayangan bekerja sama dalam kenyataan
Meskipun aturan sebelumnya ditentukan dengan baik dan konsisten, penerapan
saat ini tidak selalu mencerminkannya.
Dalam praktiknya, @property
berfungsi secara berbeda dari spesifikasi dengan cara yang konsisten
di seluruh browser, dan sebagian besar fitur lainnya memiliki bug terbuka (beberapa di antaranya
belum dirilis, jadi ada waktu untuk memperbaikinya).
Untuk menguji dan mendemonstrasikan cara kerja fitur ini dalam praktik, kami telah membuat halaman berikut: https://css-names-in-the-shadow.glitch.me/. Halaman ini memiliki beberapa iframe, masing-masing berfokus pada salah satu fitur dan menguji enam skenario:
- Referensi luar ke nama luar: tidak ada shadow DOM yang terlibat, ini seharusnya berfungsi.
- Referensi luar ke nama dalam: hal ini tidak akan berfungsi, karena hal itu berarti nama yang ditentukan dalam konteks bayangan telah bocor.
- Referensi dalam ke nama luar: ini akan berfungsi, karena nama cakupan hierarki diwarisi oleh root bayangan.
- Referensi dalam ke nama dalam: ini akan berfungsi, karena nama referensi berada dalam cakupan yang sama.
- Referensi
::part
ke nama luar: ini akan berfungsi, karena::part
dan nama dideklarasikan dalam cakupan yang sama. - Referensi
::part
ke nama dalam: hal ini tidak akan berfungsi, karena cakupan luar tidak boleh mendapatkan pengetahuan tentang nama yang dideklarasikan di dalam shadow DOM.
@keyframes
Seperti yang ditentukan dalam spesifikasi, Anda harus dapat mereferensikan nama keyframe
dari dalam root bayangan, selama aturan at @keyframes
berada dalam cakupan
ancestor. Dalam praktiknya, tidak ada browser yang menerapkan perilaku ini, dan definisi
keyframe hanya dapat dirujuk dalam cakupan tempat definisi tersebut ditentukan. Lihat
masalah 10540.
@property
Seperti yang ditentukan dalam spesifikasi, deklarasi @property
apa pun akan
diratakan ke cakupan dokumen. Namun, saat ini, di semua browser, Anda hanya dapat
mendeklarasikan @property
dalam cakupan dokumen dan deklarasi @property
dalam
root bayangan akan diabaikan.
Lihat masalah 10541.
Bug khusus browser
Fitur lainnya tidak menunjukkan perilaku yang konsisten di seluruh browser:
@font-face
diratakan ke cakupan root di Safari.- Chromium tidak mengizinkan pewarisan aturan
anchor-name
di root bayangan scroll-timeline-name
danview-timeline-name
tidak dicakup dengan benar di::part
(juga di Chromium).- Tidak ada browser yang mengizinkan deklarasi
@font-palette-values
di root bayangan. view-transition-class
dapat ditentukan di dalam root bayangan (transisi itu sendiri berada di luar root bayangan).- Firefox memungkinkan
::part
mengakses nama bayangan dalam (kueri penampung, keyframe). - Firefox dan Safari tidak mematuhi
@counter-style
di root bayangan.
Perhatikan bahwa counter-reset
, counter-set
, counter-increment
memiliki aturan yang sedikit
berbeda karena merupakan nama implisit, dan mendeklarasikan properti CSS
memiliki kumpulan aturan yang telah ditetapkan dan diuji dengan baik.
Kesimpulan
Kabar buruknya adalah saat memeriksa snapshot status interop saat ini terkait nama CSS dan shadow DOM, pengalamannya tidak konsisten dan bermasalah. Tidak ada fitur yang kami periksa di sini yang berperilaku konsisten di seluruh browser dan sesuai dengan spesifikasi. Berita baiknya adalah delta untuk membuat pengalaman konsisten adalah daftar bug dan masalah spesifikasi yang terbatas. Mari kita perbaiki. Sementara itu, ringkasan ini semoga dapat membantu jika Anda mengalami inkonsistensi yang dijelaskan dalam artikel ini.