The CSS :modal pseudo-class selects an element that is currently displayed in a modal state. It is commonly used to style an HTML dialog opened with showModal(), allowing the dialog to receive different styling while interaction with the rest of the document is blocked.

:modal Syntax

selector:modal {
  property: value;
}

The :modal pseudo-class is added directly to a selector without a space. It matches an element only while that element is in a modal state.

Basic Example

dialog:modal {
  border: 2px solid #006699;
}

This rule adds a blue border to an HTML dialog while it is displayed modally.

Background Example

dialog:modal {
  background-color: #eaf6fc;
}

This rule changes the background color of a modal dialog.

Class Selector Example

.confirmation:modal {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}

This rule adds a shadow to an element with the confirmation class while it is modal.

How :modal Works

The :modal pseudo-class matches elements placed in a modal state by the browser. While a modal element is active, interaction with the rest of the document is restricted.

Modal State

A modal element requires the user to interact with or dismiss it before returning to the underlying document.

HTML Dialog Example

<dialog id="example-dialog">
  <p>This is a modal dialog.</p>
  <button type="button" id="close-dialog">Close</button>
</dialog>

JavaScript Example

const dialog = document.getElementById("example-dialog");
dialog.showModal();

Calling showModal() opens the dialog in a modal state. The dialog then matches :modal.

Automatic State Changes

When the dialog is closed, it stops matching :modal. No manual CSS class changes are required.

Top Layer

A modal dialog is placed in the browser's top layer, allowing it to appear above ordinary document content.

The HTML <dialog> element provides a built-in way to create modal and nonmodal dialogs.

HTML Example

<button type="button" id="open-dialog">Open Dialog</button>
<dialog id="example-dialog">
  <h2>Dialog Heading</h2>
  <p>This dialog opens in a modal state.</p>
  <button type="button" id="close-dialog">Close</button>
</dialog>

CSS Example

dialog:modal {
  padding: 20px;
  border: 2px solid #006699;
  border-radius: 6px;
}

JavaScript Example

const dialog = document.getElementById("example-dialog");
document.getElementById("open-dialog").addEventListener("click", () => {
  dialog.showModal();
});
document.getElementById("close-dialog").addEventListener("click", () => {
  dialog.close();
});

Clicking the Open Dialog button displays the dialog modally. The CSS rule applies until the dialog closes.

Built-In Dialog Behavior

Modal dialogs provide built-in focus handling, keyboard dismissal behavior, and restrictions on interaction with the underlying document.

The showModal() Method

The JavaScript showModal() method opens an HTML dialog as a modal dialog.

JavaScript Syntax

dialog.showModal();

Opening a Dialog

const dialog = document.querySelector("dialog");
dialog.showModal();

The browser displays the dialog in the top layer and makes the rest of the document inert while the modal dialog is active.

Closing a Dialog

dialog.close();

Closing the dialog removes its modal state and causes it to stop matching :modal.

The Escape Key

Users can normally dismiss a modal dialog with the Escape key. Applications can handle the dialog's cancel event when appropriate.

Important Distinction

Using showModal() opens a modal dialog. Using show() opens a nonmodal dialog instead.

The <dialog> element can be opened in two different modes.

Comparison

Method Behavior Matches :modal
showModal() Opens a modal dialog and makes the rest of the document inert. Yes
show() Opens a nonmodal dialog without blocking the rest of the document. No
close() Closes an open dialog. No

CSS Example

dialog {
  border: 1px solid #999;
}
dialog:modal {
  border: 3px solid #006699;
}

Both modal and nonmodal dialogs can receive the general border. Only modal dialogs receive the thicker blue border.

The open Attribute

The open attribute indicates that a dialog is open, but it does not by itself make the dialog modal.

:modal vs. :open

The :modal and :open pseudo-classes describe different element states.

Comparison

Selector Matching Condition
:modal The element is displayed in a modal state.
:open The element is in an open state.

CSS Example

dialog:open {
  padding: 20px;
}
dialog:modal {
  border: 2px solid #006699;
}

The first rule applies when the dialog is open, whether modal or nonmodal. The second applies only while the dialog is modal.

Related Elements

The :open pseudo-class can also match other elements with an open state, such as expanded <details> elements.

Choosing Between Them

Use :modal when styling depends on modal behavior. Use :open when styling depends on whether an element is open.

Styling the Backdrop

A modal dialog can display a backdrop behind it. The CSS ::backdrop pseudo-element styles this area.

CSS Example

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

This rule applies a translucent dark background behind a modal dialog.

Combining :modal and ::backdrop

dialog:modal {
  border: 2px solid #006699;
}
dialog:modal::backdrop {
  background-color: rgba(0, 0, 0, 0.5);
}

The first rule styles the modal dialog. The second styles its backdrop only while the dialog is modal.

Backdrop vs. Dialog

The :modal pseudo-class selects the modal element itself. The ::backdrop pseudo-element selects the backdrop generated behind an element in the top layer.

Visual Clarity

A backdrop can help distinguish the active modal dialog from the underlying page content.

Fullscreen Elements

The :modal pseudo-class is not limited to HTML dialogs. Elements displayed using the Fullscreen API can also match :modal.

JavaScript Example

const element = document.getElementById("fullscreen-content");
element.requestFullscreen();

When the element enters fullscreen mode, it can match both :fullscreen and :modal.

CSS Example

:fullscreen {
  background-color: #fff;
}
:fullscreen:modal {
  padding: 20px;
}

The first rule styles fullscreen elements. The second applies when an element matches both pseudo-classes.

Fullscreen vs. Dialog

Fullscreen elements and modal dialogs have different behaviors, but both can restrict interaction with other document content.

Choosing a Selector

Use :fullscreen when styling specifically for fullscreen presentation. Use :modal when styling based on modal state.

:modal Specificity

The :modal pseudo-class contributes a specificity of 0-1-0.

Specificity Examples

Selector Specificity
:modal0-1-0
dialog:modal0-1-1
.confirmation:modal0-2-0
dialog:open:modal0-2-1
#example-dialog:modal1-1-0
dialog:modal::backdrop0-1-2

Specificity Example

dialog {
  border: 1px solid #999;
}
dialog:modal {
  border: 2px solid #006699;
}

When both selectors match and other cascade factors are equal, the :modal rule takes precedence because it has greater specificity.

Practical Uses

The :modal pseudo-class is useful for styling interfaces that temporarily require the user's attention.

Confirmation Dialogs

dialog.confirmation:modal {
  border: 2px solid #006699;
}

Emphasize a confirmation dialog while it is modal.

Form Dialogs

dialog.form-dialog:modal {
  padding: 24px;
  background-color: #fff;
}

Apply modal-specific spacing and background styling to a form dialog.

Image Previews

dialog.image-preview:modal {
  max-width: 90vw;
  max-height: 90vh;
}

Constrain the dimensions of a modal image preview.

Backdrop Styling

dialog:modal::backdrop {
  background-color: rgba(0, 0, 0, 0.6);
}

Dim the background while a modal dialog is active.

State-Based Styling

Apply different styles to a dialog depending on whether it is open modally or nonmodally.

Limitations

The :modal pseudo-class matches only elements that are in a modal state recognized by the browser.

Not Every Dialog Is Modal

A dialog opened with show() does not match :modal.

The open Attribute Is Not Enough

Adding the open attribute does not make a dialog modal.

CSS Cannot Create Modal Behavior

Styling an element with a high z-index or fixed positioning does not make it match :modal.

State Depends on Browser APIs

For HTML dialogs, the modal state is normally established with showModal().

Not a General Overlay Selector

Custom overlays built entirely with ordinary HTML and CSS do not automatically match :modal.

Backdrop Styling Is Separate

Use ::backdrop to style the area behind a modal element.

Accessibility

Modal interfaces should be accessible to keyboard users and assistive technologies.

Use Native Dialogs

Prefer the HTML <dialog> element and showModal() when a modal dialog is appropriate. They provide built-in modal behavior and focus handling.

Provide an Accessible Name

<dialog aria-labelledby="dialog-title">
  <h2 id="dialog-title">Confirm Action</h2>
  <p>Do you want to continue?</p>
</dialog>

Associate the dialog with a visible heading or another appropriate accessible label.

Provide a Close Control

Include a clearly labeled way to dismiss the dialog when dismissal is appropriate.

Keyboard Interaction

Ensure users can operate the dialog with a keyboard and return to the underlying content after closing it.

Focus Visibility

dialog button:focus-visible {
  outline: 2px solid #006699;
  outline-offset: 2px;
}

Keep keyboard focus indicators visible inside modal dialogs.

Avoid Unnecessary Modals

Use modal dialogs only when the user must complete or dismiss an interaction before continuing with the underlying page.

Best Practices

  • Use :modal when styling depends on an element's actual modal state.
  • Use showModal() to open native HTML dialogs modally.
  • Use show() when a nonmodal dialog is appropriate.
  • Use :open for styles that should apply to both modal and nonmodal open dialogs.
  • Use ::backdrop to style the background behind a modal element.
  • Provide an accessible name and appropriate close controls.
  • Keep keyboard focus indicators visible.
  • Use :fullscreen for styles specific to fullscreen elements.
  • Do not assume an ordinary overlay or high z-index creates modal behavior.

:modal Example

This example opens an HTML dialog using showModal(). The :modal pseudo-class applies a blue border and shadow while the dialog is modal. The ::backdrop pseudo-element dims the page behind it.

HTML

<button type="button" id="open-modal">Open Modal Dialog</button>
<dialog id="modal-demo" aria-labelledby="modal-title">
  <h2 id="modal-title">Modal Dialog</h2>
  <p>This dialog is displayed in a modal state.</p>
  <button type="button" id="close-modal">Close Dialog</button>
</dialog>

CSS

#modal-demo {
  max-width: 260px;
  padding: 20px;
  border: 1px solid #999;
  border-radius: 6px;
}
#modal-demo:modal {
  border: 3px solid #006699;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}
#modal-demo::backdrop {
  background-color: rgba(0, 0, 0, 0.5);
}

JavaScript

const dialog = document.getElementById("modal-demo");
document.getElementById("open-modal").addEventListener("click", () => {
  dialog.showModal();
});
document.getElementById("close-modal").addEventListener("click", () => {
  dialog.close();
});

Browser Result

Play in Editor

Note: Click Open Modal Dialog to display the dialog. While it is open modally, the dialog matches :modal. Click Close Dialog or press Escape to dismiss it.

Browser Support

Baseline: Widely available. The :modal pseudo-class is supported in modern versions of Chrome, Edge, Firefox, Safari, and other major browsers.

For current compatibility information, visit Can I Use? .

Specifications

The :modal pseudo-class is defined in CSS Selectors Level 4 as an element state pseudo-class. It matches elements that are in a modal state.

Selectors Level 4 - :modal