JAVASCRIPT
Creating an Encapsulated Web Component with Shadow DOM
Build a reusable Web Component with Shadow DOM for style and markup encapsulation, ensuring component-specific logic and styling isolation.
class MyCustomComponent extends HTMLElement {
constructor() {
super(); // Always call super() first in constructor
// Attach a shadow DOM to the custom element
// 'open' mode means JavaScript can access the shadow DOM from the outside.
// 'closed' mode means JavaScript outside the shadow root cannot access it.
const shadowRoot = this.attachShadow({ mode: 'open' });
// Create and append elements to the shadow DOM
const wrapper = document.createElement('div');
wrapper.setAttribute('class', 'component-wrapper');
wrapper.innerHTML = `
<h1>Hello from Shadow DOM!</h1>
<p>This content is encapsulated.</p>
<slot name="footer">Default Footer Content</slot>
`;
// Add some styles to the shadow DOM
const style = document.createElement('style');
style.textContent = `
.component-wrapper {
font-family: sans-serif;
border: 2px solid #3498db;
padding: 15px;
border-radius: 8px;
background-color: #ecf0f1;
text-align: center;
margin-bottom: 10px;
}
h1 {
color: #2c3e50;
}
p {
color: #7f8c8d;
}
::slotted([slot="footer"]) {
font-style: italic;
color: #9b59b6;
}
`;
shadowRoot.appendChild(style);
shadowRoot.appendChild(wrapper);
}
// Optional: lifecycle callbacks
connectedCallback() {
console.log('MyCustomComponent added to document.');
}
disconnectedCallback() {
console.log('MyCustomComponent removed from document.');
}
}
// Define the custom element, linking it to the class
customElements.define('my-custom-component', MyCustomComponent);
// How to use in HTML:
// <my-custom-component>
// <span slot="footer">Custom Footer</span>
// </my-custom-component>
// Or simply: <my-custom-component></my-custom-component>
How it works: This snippet demonstrates creating a basic Web Component with a Shadow DOM for true encapsulation of its markup and styles. By calling `this.attachShadow({ mode: 'open' })`, a new isolated DOM tree is created where internal elements, styles, and scripts won't leak out to the main document or affect external elements. This promotes reusability and maintainability by preventing CSS collisions and keeping component logic self-contained. The use of `<slot>` elements allows consumers of the component to inject their own content into predefined slots within the Shadow DOM.