Creates a fullscreen modal from Shadow DOM
HTML
<div class="navbar">Navbar (z-index: 1000)</div>
<div class="page-content">
<p>This is the main page content.</p>
<button onclick="document.querySelector('custom-modal').open()">Open Modal</button>
</div>
<custom-modal></custom-modal>
CSS
/* Simulate other UI elements */
.page-content {
position: relative;
z-index: 1;
padding: 20px;
background: lightgray;
}
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 50px;
background: #333;
color: white;
z-index: 1000;
display: flex;
align-items: center;
padding: 0 1em;
}
/* Host element must have high z-index if it's not body-rooted */
custom-modal {
position: relative;
z-index: 2000; /* Must be higher than the navbar */
}
JavaScript
class CustomModal extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
.modal {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.6);
display: none;
align-items: center;
justify-content: center;
z-index: 9999; /* z-index inside Shadow DOM */
}
.modal-content {
background: white;
padding: 2em;
border-radius: 8px;
box-shadow: 0 0 20px rgba(0,0,0,0.2);
}
</style>
<div class="modal" id="modal">
<div class="modal-content">
<p>This is a fullscreen modal from Shadow DOM!</p>
<button id="closeBtn">Close</button>
</div>
</div>
`;
}
connectedCallback() {
this.shadowRoot.getElementById('closeBtn').addEventListener('click', () => this.close());
}
open() {
this.shadowRoot.getElementById('modal').style.display = 'flex';
}
close() {
this.shadowRoot.getElementById('modal').style.display = 'none';
}
}
customElements.define('custom-modal', CustomModal);