Nama CSS yang ditetapkan oleh penulis dan shadow DOM seharusnya bisa digunakan bersama. Namun, browser tidak konsisten dengan spesifikasi, terkadang dengan masing-masing satu lagi, dan setiap nama CSS tidak konsisten dengan cara yang sedikit berbeda.
Artikel ini mendokumentasikan status terkini perilaku nama CSS yang ditetapkan penulis lintas cakupan bayangan, dengan harapan menjadi 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, awalnya
diperkenalkan untuk aturan @keyframes
, yang menentukan <keyframe-name>
sebagai
ID khusus atau string. Tujuan dari 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 lain yang menggunakan nama CSS adalah font, deklarasi properti, kueri container, dan yang baru-baru ini menampilkan transisi, penempatan anchor, dan animasi berbasis scroll. Tabel tidak komprehensif berikut ini menyertakan nama yang diperiksa statusnya.
Fitur | Pernyataan nama | Referensi nama |
---|---|---|
Frame utama | @keyframes |
animation-name |
Font | @font-face { }
@font-palette-values |
font-family
font-palette |
Pernyataan Properti | @property |
Semua properti khusus |
Lihat transisi | view-transition-name
view-transition-class |
::view-transition-group() |
Pemosisian Anchor | anchor-name |
position-anchor |
Animasi berbasis scroll | animation-timeline |
view-timeline-name
scroll-timeline-name |
Gaya penghitung | @counter-style
Counter-reset
counter-set
counter-increment |
list-style |
Kueri container | container-name |
@container |
Variabel CSS | --something |
var(--something) |
Halaman | @page |
Seperti yang dapat dilihat dalam tabel, name CSS biasanya memiliki CSS yang sesuai
referensi ini. Misalnya, animation-name
adalah referensi ke @keyframes
nama. Nama CSS berbeda dengan nama yang ditetapkan dalam DOM, seperti atribut
serta nama tag, seperti yang dideklarasikan, kemudian direferensikan dalam konteks
spreadsheet gaya.
Bagaimana nama berhubungan dengan shadow DOM
Sementara nama CSS dibuat untuk menciptakan hubungan antara berbagai bagian dokumen atau stylesheet, Shadow DOM adalah dibuat untuk melakukan hal sebaliknya. IA mengenkapsulasi hubungan sehingga tidak bocor komponen web yang seharusnya memiliki namespace sendiri.
Dengan menyatukan nama CSS dan shadow DOM, pengalaman penyusunan komponen web harus terasa cukup ekspresif untuk bisa fleksibel tetapi terkendala untuk stabil.
Teori ini bagus. Dalam praktiknya, browser tidak konsisten dengan cara CSS nama berinteroperasi dengan shadow DOM, keduanya di antara fitur yang sama browser, di seluruh browser, serta di antara fitur dan spesifikasi.
Cara nama dan shadow DOM bekerja sama
Untuk memahami masalahnya, penting untuk memahami bagaimana bagian-bagian CSS ini harus bekerja sama secara teori.
Aturan umum
Aturan umum tentang bagaimana nama CSS berperilaku di seluruh pohon bayangan didefinisikan dalam Spesifikasi Cakupan CSS Level 1. Ringkasnya: nama CSS bersifat global di dalam cakupan tempat nama tersebut didefinisikan, yang berarti dapat diakses dari pohon bayangan turunan, tetapi tidak dari pohon seinduk atau pohon bayangan nenek moyang. 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 lain, properti CSS tidak dienkapsulasi oleh shadow DOM.
Sebaliknya, ini adalah cara umum untuk meneruskan parameter pada bayangan yang berbeda
pohon.
Hal ini membuat
Deskripsi @property
spesial: seharusnya berperilaku seperti
deklarasi tipe {i>document-global<i} yang
menentukan cara properti bernama berfungsi. Karena properti harus cocok
di seluruh pohon bayangan, ketidakcocokan deklarasi properti akan menyebabkan
hasil, sehingga deklarasi @property
ditentukan untuk diratakan dan di-resolve
sesuai dengan urutan dokumen.
Cara kerja aturan dengan ::part
Bagian bayangan
mengekspos elemen dalam pohon bayangan ke pohon induknya. Dengan demikian,
struktur induk dapat mengakses elemen tersebut serta menata gayanya menggunakan ::part
.
Karena ::part
mengizinkan dua cakupan hierarki untuk menata gaya elemen yang sama,
ditentukan urutannya:
- Pertama, periksa gaya di dalam konteks bayangan. Ini adalah "default" gaya dari suatu bagian.
- Kemudian, terapkan gaya eksternal seperti yang ditentukan dalam
::part
. Ini adalah "disesuaikan" gaya dari suatu bagian. - Kemudian, terapkan gaya internal apa pun yang ditentukan bersama dengan
!important
. Ini memungkinkan elemen khusus mendeklarasikan bahwa properti tertentu dari bagian tidak dapat disesuaikan oleh::part
.
Ini berarti bahwa nama dari dalam shadow DOM tidak bisa direferensikan dari
::part
, karena ::part
adalah gaya cakupan host, bukan cakupan bayangan
gaya. 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
secara terprogram menggunakan skrip, akan menjadi cakupan tempat elemen
yang akan digunakan. Itu karena untuk menerapkan gaya
ke elemen yang perlu Anda akses
{i>handle<i} elemen, dan kemudian ke
akar bayangan itu sendiri.
Cara nama CSS dan shadow DOM bekerja sama dalam kenyataan
Meskipun aturan sebelumnya telah didefinisikan
dengan baik dan konsisten, aturan yang
tidak selalu mencerminkan hal itu.
Dalam praktiknya, @property
berfungsi secara berbeda dari spesifikasi secara konsisten
di seluruh {i>browser<i}, dan sebagian besar fitur lainnya
memiliki {i>bug<i} terbuka (beberapa di antaranya adalah
belum dirilis, jadi masih ada waktu untuk memperbaikinya).
Untuk menguji dan mendemonstrasikan cara kerja fitur ini dalam praktiknya, 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 harus Anda.
- Referensi luar ke nama bagian dalam: ini seharusnya tidak berfungsi, karena akan berarti nama yang didefinisikan dalam konteks bayangan telah bocor.
- Referensi dalam ke nama luar: ini seharusnya berfungsi, sebagai nama cakupan hierarki diwarisi oleh akar bayangan.
- Inner reference to inner name: ini seharusnya berfungsi, baik karena merupakan nama berada dalam cakupan yang sama.
- Referensi
::part
ke nama luar: ini seharusnya berfungsi, baik karena::part
dan namanya dideklarasikan dalam cakupan yang sama. - Referensi
::part
ke nama dalam: ini seharusnya tidak berfungsi, karena cakupan luar seharusnya tidak mendapatkan pengetahuan tentang nama yang dideklarasikan di dalam shadow DOM.
@keyframes
Seperti yang didefinisikan dalam spesifikasi, Anda seharusnya dapat mereferensikan nama keyframe
dari dalam root bayangan, selama @keyframes
pada aturan berada dalam ancestor
ruang lingkup proyek. Dalam praktiknya, tidak ada browser yang menerapkan perilaku ini, dan keyframe
hanya dapat dirujuk dalam ruang
lingkup di mana definisi tersebut didefinisikan. Lihat
masalah 10540.
@property
Sebagaimana ditentukan dalam spesifikasi, setiap deklarasi @property
akan
diratakan ke ruang
lingkup dokumen. Namun saat ini, di semua browser, Anda hanya dapat
deklarasikan @property
dalam cakupan dokumen dan pernyataan @property
dalam
akar bayangan diabaikan.
Lihat masalah 10541.
Bug khusus browser
Fitur lainnya tidak menunjukkan perilaku yang konsisten di seluruh browser:
@font-face
disatukan ke cakupan root di Safari.- Chromium tidak mengizinkan pewarisan aturan
@anchor-name
dalam root bayangan @scroll-timeline-name
dan@view-timeline-name
tidak dicakup dengan benar di::part
(juga di Chromium).- Tidak ada browser yang mengizinkan deklarasi
@font-palette-values
dalam root bayangan. view-transition-class
dapat ditentukan di dalam root bayangan (transisi itu sendiri berada di luar shadow-root).- Firefox memungkinkan
::part
mengakses nama bayangan dalam (kueri container, keyframe). - Firefox dan Safari tidak mematuhi
@counter-style
dalam root bayangan.
Perhatikan bahwa counter-reset
, counter-set
, counter-increment
memiliki sedikit
aturan yang berbeda karena merupakan nama implisit, dan mendeklarasikan properti CSS
memiliki seperangkat aturan
yang mapan dan teruji dengan baik.
Kesimpulan
Kabar buruknya adalah ketika memeriksa {i>snapshot<i} dari status interop saat ini sehubungan dengan nama CSS dan {i>shadow DOM<i}, pengalaman itu tidak konsisten dan banyak bug. Tidak ada fitur yang telah kita pelajari di sini berperilaku konsisten di seluruh browser dan sesuai dengan spesifikasi. Kabar baiknya adalah bahwa delta untuk membuat pengalaman konsisten adalah daftar {i>bug<i} dan masalah spesifikasi. Mari kita perbaiki. Sementara itu, ringkasan ini diharapkan dapat membantu jika Anda mengalami kesulitan dengan inkonsistensi yang dijelaskan dalam artikel ini.