CSS :modal Pseudo-Class

The CSS :modal pseudo-class matches an element while it is in a modal state, meaning interaction outside that element is blocked until it is dismissed. A common example is an HTML <dialog> opened with showModal(). Use :modal for the dialog state and ::backdrop for the layer behind it.

The <dialog> Element

The HTML <dialog> element represents a dialog box or other interactive component, such as a modal window. It provides a native way to create modals without relying on external libraries.

Basic Structure


<dialog id="myModal">
    <p>This is a modal dialog.</p>
    <button id="closeBtn">Close</button>
</dialog>

Opening and Closing the Dialog

You can control the dialog's visibility using JavaScript:


// Open the dialog
document.getElementById('myModal').showModal();

// Close the dialog
document.getElementById('myModal').close();

Styling the Modal Dialog

The <dialog> element can be styled using CSS like any other element. Additionally, you can style the backdrop using the ::backdrop pseudo-element.

Example CSS


dialog {
    width: 400px;
    padding: 20px;
    border: none;
    border-radius: 8px;
    box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}

dialog::backdrop {
    background: rgba(0, 0, 0, 0.5);
}

#openBtn, #closeBtn {
    padding: 10px 20px;
    cursor: pointer;
}

Complete Example

HTML


<button id="openBtn">Open Modal</button>

<dialog id="myModal">
    <h2>Modal Title</h2>
    <p>This is the modal content.</p>
    <button id="closeBtn">Close</button>
</dialog>

CSS


dialog {
    width: 400px;
    padding: 20px;
    border: none;
    border-radius: 8px;
    box-shadow: 0 5px 15px rgba(0,0,0,0.3);
    text-align: center;
}

dialog::backdrop {
    background: rgba(0, 0, 0, 0.5);
}

#openBtn, #closeBtn {
    padding: 10px 20px;
    margin-top: 10px;
    cursor: pointer;
}

JavaScript


const openBtn = document.getElementById('openBtn');
const closeBtn = document.getElementById('closeBtn');
const myModal = document.getElementById('myModal');

openBtn.addEventListener('click', () => {
    myModal.showModal();
});

closeBtn.addEventListener('click', () => {
    myModal.close();
});

Using the ::backdrop Pseudo-element

The ::backdrop pseudo-element targets the background behind the dialog when it is open. You can style it to create an overlay effect:


dialog::backdrop {
    background: rgba(0, 0, 0, 0.8);
}

This adds a semi-transparent black overlay behind the dialog, focusing the user's attention on the modal content.

Creating a Modal Without <dialog>

If you prefer not to use the <dialog> element, you can create a modal using a regular <div> and CSS:

HTML


<button id="openBtn">Open Modal</button>

<div id="modal" class="modal">
    <div class="modal-content">
        <span id="closeBtn" class="close">&times;</span>
        <h2>Modal Title</h2>
        <p>This is the modal content.</p>
    </div>
</div>

CSS


.modal {
    display: none; /* Hidden by default */
    position: fixed; 
    z-index: 1; 
    left: 0;
    top: 0;
    width: 100%; 
    height: 100%; 
    overflow: auto;
    background: rgba(0,0,0,0.5); /* Overlay effect */
}

.modal-content {
    background-color: #fff;
    margin: 15% auto; 
    padding: 20px;
    border: none;
    width: 80%;
    max-width: 500px;
    border-radius: 8px;
}

.close {
    color: #aaa;
    float: right;
    font-size: 28px;
    cursor: pointer;
}

JavaScript


const openBtn = document.getElementById('openBtn');
const closeBtn = document.getElementById('closeBtn');
const modal = document.getElementById('modal');

openBtn.addEventListener('click', () => {
    modal.style.display = 'block';
});

closeBtn.addEventListener('click', () => {
    modal.style.display = 'none';
});

// Close modal when clicking outside of the modal content
window.addEventListener('click', (event) => {
    if (event.target === modal) {
        modal.style.display = 'none';
    }
});

Conclusion

While there is no ::modal pseudo-class in CSS, you can effectively create and style modal dialogs using the <dialog> element and the ::backdrop pseudo-element. For broader compatibility or custom behavior, using a combination of HTML, CSS, and JavaScript with standard elements like <div> is also a viable approach.