Langsung ke konten
Belajar HTML & CSS

Apa Itu Shadow DOM?

Foto TaufiqOleh Taufiq
Apa Itu Shadow DOM?

Apa itu Shadow DOM? Pertanyaan ini sering muncul saat pertama kali Anda menyelami dunia Web Components. Shadow DOM adalah mekanisme dalam spesifikasi Web Components yang memungkinkan sebuah elemen HTML memiliki pohon DOM tersembunyi — terisolasi dari style dan script halaman utama. Gampangnya begini: bayangkan sebuah kamar pribadi di dalam rumah besar. Furnitur di kamar itu berdiri sendiri, tidak terpengaruh dekorasi di ruang tamu, dan sebaliknya. Pernahkah Anda frustrasi karena CSS satu komponen tiba-tiba mengubah tampilan elemen lain yang seharusnya tidak terpengaruh? Shadow DOM adalah jawaban atas masalah klasik itu. Dalam panduan ini, kita akan membahas Shadow DOM dari dasar sampai implementasi praktis.

Kenapa Shadow DOM Diperlukan?

Sebelum Shadow DOM ada, seluruh elemen di halaman web berbagi satu pohon DOM yang sama. Artinya, CSS dari satu komponen bisa dengan mudah menimpa style komponen lain. Ini masalah besar saat developer membangun widget yang di-embed di berbagai situs — misalnya tombol share media sosial, widget chat customer service, atau form pembayaran third-party. Tanpa isolasi, style dari host page bisa merusak tampilan widget, dan sebaliknya.

Konflik style seperti ini sering muncul di proyek berskala besar di mana beberapa tim bekerja di komponen berbeda. Salah satu tim bisa saja mengubah selector CSS yang ternyata juga menargetkan elemen di komponen tim lain. Shadow DOM menyelesaikan masalah ini dengan menciptakan batas tegas antara DOM internal komponen dengan DOM luar halaman. Tanpa Shadow DOM, Anda harus bergantung pada naming convention yang longgar dan harapan bahwa tidak ada yang bentrok.

Penjelasan Konsep Shadow DOM

Shadow DOM adalah bagian dari spesifikasi Web Components yang dikelola oleh W3C. Fitur ini memungkinkan sebuah elemen HTML memiliki “anak” DOM yang tersembunyi — disebut shadow tree — yang tidak terlihat dari DOM utama dan tidak bisa diakses oleh CSS atau JavaScript dari luar.

Istilah penting yang perlu Anda pahami:

  • Shadow host — elemen HTML yang menjadi “rumah” dari shadow DOM. Misalnya, <my-card> adalah shadow host.
  • Shadow tree — pohon DOM tersembunyi di dalam shadow host. Template, style, dan struktur internal komponen didefinisikan di sini.
  • Light DOM — konten asli dari elemen yang didefinisikan oleh si pemakai. Kalau Anda menulis <my-card>Judul</my-card>, maka “Judul” adalah light DOM.
  • Shadow root — titik masuk dari shadow tree, root node dari DOM tersembunyi tersebut.

Analogi yang lebih detail: bayangkan sebuah restoran. Di bagian depan ada ruang makan yang bisa dilihat semua tamu (light DOM). Tapi di balik dinding, ada dapur tersembunyi (shadow tree) yang hanya bisa diakses koki dan staf dapur (shadow root). Tamu tidak bisa masuk ke dapur, dan aromanya pun tidak terlalu keluar ke ruang makan karena ada exhaust hood yang terisolasi. Nah, sekarang mari kita lihat bagaimana solusi ini bekerja secara teknis.

Cara Kerja Shadow DOM

topik tersebut bekerja dengan memisahkan pohon DOM menjadi dua bagian terpisah yang terhubung secara visual saat rendering. Browser menggabungkan light DOM dan topik tersebut menjadi satu tampilan visual, tapi struktur internalnya tetap terpisah. Yang membuat topik tersebut powerful adalah konsep scoped CSS. Style yang didefinisikan di dalam shadow tree hanya berlaku untuk elemen-elemen di dalam shadow tree itu saja. Tidak ada kebocoran style keluar, dan tidak ada style dari luar yang masuk — kecuali CSS custom properties yang sengaja di-expose.

Tapi gimana kalau saya ingin konten pengguna masuk ke dalam komponen? Di sinilah slot elements berperan. Slot memungkinkan light DOM dimasukkan ke posisi tertentu di dalam shadow tree, menjadikan komponen fleksibel tanpa mengorbankan isolasi style. Slot bisa berupa named slot (diberi nama tertentu) atau default slot (menangkap semua konten yang tidak diberi nama slot).

Cara Membuat topik tersebut dengan JavaScript

Oke, lanjut ke bagian yang paling ditunggu — implementasi kode. Membuat topik tersebut cukup sederhana dengan memanggil method attachShadow() pada elemen. Berikut contoh lengkap komponen kartu dengan topik tersebut:

JavaScript Snippet JavaScript
// Membuat komponen custom dengan topik tersebut
class MyCard extends HTMLElement { constructor() { super(); // Attach topik tersebut ke elemen ini // mode 'open' artinya shadow root bisa diakses dari luar untuk debugging const shadow = this.attachShadow({ mode: 'open' }); // Buat template HTML untuk komponen const template = document.createElement('template'); template.innerHTML = ` <style> /* Style ini HANYA berlaku di dalam komponen */ .card { border: 2px solid #3498db; border-radius: 12px; padding: 20px; max-width: 320px; font-family: sans-serif; box-shadow: 0 4px 12px rgba(0,0,0,0.1); } .card h3 { color: #2c3e50; margin-top: 0; } ::slotted(p) { color: #555; line-height: 1.6; } </style> <div class="card"> <h3><slot name="title"></slot></h3> <slot></slot> </div> `; // Clone template dan masukkan ke topik tersebut shadow.appendChild(template.content.cloneNode(true)); }
}
customElements.define('my-card', MyCard);

Penjelasan line-by-line:

  • class MyCard extends HTMLElement — Membuat class komponen yang mewarisi HTMLElement, standar untuk Web Components.
  • this.attachShadow({ mode: 'open' }) — Membuat shadow root dan menghubungkannya ke elemen. Mode ‘open’ memungkinkan akses dari JavaScript luar.
  • template.innerHTML — Berisi HTML dan CSS shadow tree. Style tertulis langsung karena scoped CSS hanya berlaku di dalam komponen.
  • ::slotted(p) — Selector khusus untuk style konten yang masuk melalui slot dari light DOM.
  • shadow.appendChild(template.content.cloneNode(true)) — Mengklon template dan memasukkannya ke shadow root.
  • customElements.define('my-card', MyCard) — Mendaftarkan komponen agar bisa digunakan di HTML.

Penggunaan di HTML:

HTML Snippet HTML
<my-card> <span slot="title">Judul Kartu</span> <p>Ini konten yang masuk melalui slot default.</p>
</my-card>

topik tersebut Mode: Open vs Closed

Ketika memanggil attachShadow(), Anda harus menentukan mode-nya. Mode ‘open’ memungkinkan shadow root diakses dari JavaScript luar menggunakan element.shadowRoot. Ini memudahkan debugging dan testing — sangat disarankan saat development. Mode ‘closed’ membuat shadow root tidak bisa diakses dari luar; element.shadowRoot mengembalikan null. Memberikan privasi lebih, tapi debugging lebih sulit. Dalam praktik sehari-hari, kebanyakan developer menggunakan mode ‘open’. Mode ‘closed’ lebih cocok untuk komponen keamanan atau payment widget. Yang menarik, browser DevTools tetap bisa menampilkan shadow tree meskipun mode-nya closed — fitur ini sangat membantu saat debugging komponen production.

Slot: Sistem Memasukkan Konten ke topik tersebut

Salah satu fitur paling powerful dari topik tersebut adalah sistem slot. Slot memungkinkan Anda menentukan titik masuk untuk light DOM di dalam template shadow tree. Ada dua jenis slot: named slot (diberi atribut name, konten pengguna menggunakan slot="nama-slot") dan default slot (slot tanpa nama yang menangkap semua konten yang tidak diberi nama slot). Sistem slot inilah yang menjadikan komponen topik tersebut fleksibel. Anda bisa menentukan di mana konten pengguna ditampilkan tanpa mengorbankan isolasi style yang menjadi keunggulan utama topik tersebut.

topik tersebut vs Light DOM

Perbandingan langsung: Light DOM adalah DOM standar di mana semua elemen berada dalam satu pohon DOM, CSS global berlaku di mana saja, mudah di-debug tapi rentan konflik style. topik tersebut adalah DOM tersembunyi yang diisolasi, style scoped, struktur tersembunyi, tidak ada konflik style tapi debugging perlu akses shadow root. Bayangkan Light DOM seperti ruang kerja bersama di mana semua orang bisa mengatur meja siapa saja. topik tersebut seperti ruang kerja pribadi — Anda bisa mendekorasi sesuka hati tanpa mengganggu orang lain. Secara teknis, browser menggabungkan keduanya saat rendering.

Studi Kasus: topik tersebut di Komponen Populer

Saat pertama kali belajar topik tersebut, saya bingung kapan sebaiknya menggunakannya. Ternyata banyak produk sudah mengadopsinya. Elemen native browser seperti <video>, <input>, dan <select> menggunakan topik tersebut internal untuk merender controls — itulah mengapa style default browser sulit dioverride. Lit dari Google menjadikan topik tersebut sebagai rendering strategy utama untuk komponen Material Design. Stencil.js dari Ionic secara default menggunakan topik tersebut untuk isolasi komponen di Angular, React, dan Vue. Google menggunakannya di elemen <google-map> dan <google-signin-button>. Baca dokumentasi lengkapnya di MDN Web Docs — Using topik tersebut.

Security: XSS dan topik tersebut

topik tersebut memberikan isolasi style dan DOM, tapi bukan isolasi keamanan absolut. Cross-site scripting (XSS) tetap bisa terjadi jika Anda merender user input di dalam shadow tree tanpa sanitasi. Selalu sanitasi input menggunakan library seperti DOMPurify. Event leaking juga perlu diwaspadai — beberapa event seperti click, focus, dan blur tetap menembus batas topik tersebut. CSS custom properties tetap bisa mewarisi dari luar ke dalam shadow tree, powerful untuk theming tapi bisa jadi jebakan jika mengandalkan isolasi CSS untuk menyembunyikan data sensitif. Pelajari lebih lanjut tentang ancaman keamanan web di OWASP — Cross-Site Scripting.

Browser Support

topik tersebut sudah didukung oleh semua browser modern: Chrome, Firefox, Safari, dan Edge. Cek status kompatibilitas di Can I Use — topik tersebut v1. Untuk browser lama, gunakan Web Components polyfill. Lihat juga Spesifikasi topik tersebut dari W3C untuk detail teknis.

Common Mistakes

Beberapa jebakan yang sering dialami developer pemula. Mengakses shadow root dari mode closed — gunakan mode ‘open’ untuk debugging. Lupa menggunakan ::slotted() — CSS dari light DOM tidak masuk ke shadow tree. Selector luar tidak menemukan elemen dalam topik tersebut — akses shadow root dulu. Menggunakan innerHTML untuk manipulasi shadow tree — sebaiknya via DOM API langsung untuk hindari XSS. Tidak mempertimbangkan a11y — komponen topik tersebut tetap harus memperhatikan aksesibilitas seperti aria attributes dan keyboard navigation.

Tips Praktis

  • Mulai dengan mode ‘open’ saat development. Beralih ke ‘closed’ hanya jika ada alasan keamanan kuat.
  • Gunakan CSS custom properties untuk menyampaikan tema dari luar ke dalam shadow tree — cara terbaik untuk theming.
  • Manfaatkan DevTools modern — Chrome dan Firefox sudah menampilkan shadow tree di Elements panel.
  • Kombinasikan dengan Custom Events untuk komunikasi antara topik tersebut dan world luar.
  • Validasi kompatibilitas sebelum production. Gunakan polyfill jika target audiens masih menggunakan browser lama.

Rangkuman

  • topik tersebut adalah mekanisme isolasi DOM yang memungkinkan komponen memiliki style dan struktur tersembunyi tanpa bentrok dengan halaman induk.
  • Shadow tree terdiri dari scoped CSS dan template HTML yang sepenuhnya dikontrol oleh komponen.
  • Slot memungkinkan konten pengguna (light DOM) dimasukkan ke posisi tertentu di dalam shadow tree tanpa mengorbankan isolasi.
  • Mode ‘open’ untuk debugging mudah, mode ‘closed’ untuk privasi maksimal.
  • Browser modern sudah mendukung topik tersebut secara native. Pelajari lebih lanjut di panduan Web Components lengkap.

topik tersebut mungkin terasa rumit di awal, tapi setelah memahami konsepnya, ini adalah solusi elegan untuk masalah isolasi komponen. Mulai coba bangun komponen sederhana dengan topik tersebut hari ini, dan rasakan bedanya sendiri!

Hal yang sering ditanyakan seputar Shadow DOM dalam Web Development

Apa fungsi utama Shadow DOM dalam arsitektur web modern?

Shadow DOM menyediakan enkapsulasi penuh untuk styling CSS dan struktur DOM, mencegah aturan gaya komponen bocor ke luar atau terpengaruh oleh stylesheet global dokumen utama.

Bagaimana hubungan antara Shadow DOM dan Web Components?

Shadow DOM merupakan salah satu pilar standar utama Web Components (bersama Custom Elements dan HTML Templates) yang memungkinkan pembuatan widget web mandiri yang dapat digunakan kembali.

Kapan pengembang sebaiknya menggunakan Shadow DOM?

Saat membangun design system modular, widget pihak ketiga (seperti widget chat atau pemutar video), atau komponen UI kompleks yang membutuhkan isolasi gaya yang ketat.

Komentar

Memuat komentar…

Tinggalkan Komentar

Alamat email Anda tidak akan dipublikasikan.