CSS :open Pseudo-Class

The CSS :open pseudo-class selects elements that have an open or expanded state and are currently open. It can style elements such as <details>, <dialog>, and certain <select> controls without requiring JavaScript to add or remove CSS classes.

:open Syntax

selector:open {
  property: value;
}

The :open pseudo-class matches supported elements while they are in their open state. It does not accept arguments or use parentheses.

Basic Example

details:open {
  background-color: #eaf6fc;
}

Applies a light blue background to a <details> element when it is expanded.

Dialog Example

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

Styles a dialog while it is open.

Select Example

select:open {
  border-color: #006699;
}

Changes the border of a supported select control while its picker is open.

No Parentheses

Write :open, not :open(). It is a state-based pseudo-class without arguments.

How :open Works

The browser determines whether an element supports an open state and whether that state is currently active. The :open pseudo-class matches only while both conditions are satisfied.

Open and Closed States

details {
  border: 1px solid #ccc;
}
details:open {
  border-color: #006699;
  background-color: #eaf6fc;
}

The default rule applies whether the details element is open or closed. The second rule applies only while it is open.

Automatic State Updates

When a user expands or collapses a supported element, the browser updates selector matching automatically.

Supported Element Behavior

The meaning of an open state depends on the element. A details element is expanded, a dialog is displayed as an open dialog, and a supported select control has its picker open.

Not a General Visibility Selector

The :open pseudo-class does not match an ordinary element simply because it is visible or has display: block.

Open <details> Elements

The <details> element provides a disclosure widget that users can expand or collapse. The :open pseudo-class matches when its content is expanded.

HTML Example

<details>
  <summary>View additional information</summary>
  <p>This content appears when the details element is open.</p>
</details>

CSS Example

details {
  padding: 12px;
  border: 1px solid #ccc;
}
details:open {
  border-color: #006699;
  background-color: #eaf6fc;
}

When the user activates the summary, the details element expands and receives the open-state styling.

Styling the Summary

details:open > summary {
  color: #006699;
  font-weight: bold;
}

Changes the summary text while its parent details element is expanded.

Initially Open Details

<details open>
  <summary>Expanded by default</summary>
  <p>This content is initially visible.</p>
</details>

The open attribute makes the details element initially expanded, so it matches :open when the page loads.

Open <dialog> Elements

The <dialog> element represents a dialog box. The :open pseudo-class matches while the dialog is open, whether it is modal or non-modal.

HTML Example

<dialog id="example-dialog">
  <p>This is a dialog box.</p>
  <button type="button" id="close-dialog">Close</button>
</dialog>
<button type="button" id="show-dialog">Open Dialog</button>

CSS Example

dialog:open {
  border: 2px solid #006699;
  border-radius: 6px;
  background-color: #eaf6fc;
}

JavaScript Example

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

The dialog matches :open after showModal() opens it. It stops matching when close() closes it.

Modal and Non-Modal Dialogs

Both show() and showModal() open a dialog. The :open pseudo-class can match either state, while :modal matches the modal state specifically.

Dialog Backdrop

dialog:open::backdrop {
  background-color: rgb(0 0 0 / 50%);
}

Styles the backdrop of an open modal dialog. A non-modal dialog does not receive a modal backdrop.

Open <select> Controls

The :open pseudo-class can match a select control while its selection picker is open. This behavior applies to supported controls that display a picker, not list boxes that show multiple options continuously.

HTML Example

<label for="layout">Choose a layout:</label>
<select id="layout" name="layout">
  <option value="grid">Grid</option>
  <option value="flexbox">Flexbox</option>
  <option value="block">Block</option>
</select>

CSS Example

select {
  padding: 8px;
  border: 2px solid #ccc;
}
select:open {
  border-color: #006699;
  background-color: #eaf6fc;
}

In browsers that support this behavior, the select control receives the open-state styling while its picker is displayed.

List Boxes

<select size="3">
  <option>HTML</option>
  <option>CSS</option>
  <option>JavaScript</option>
</select>

A select element displayed as a list box does not have the same expandable picker behavior and does not match :open.

Browser Differences

Native select controls can behave differently across browsers and operating systems. Test open-state styling on the browsers you support.

Styling the Closed State

Use :not(:open) to select supported elements when they are not open.

Closed Details

details:not(:open) {
  background-color: #f5f5f5;
}
details:open {
  background-color: #eaf6fc;
}

Applies different backgrounds to collapsed and expanded details elements.

Closed Dialog

dialog:not(:open) {
  border-color: #ccc;
}
dialog:open {
  border-color: #006699;
}

The closed-state rule matches a closed dialog, although a closed dialog is normally not rendered.

Target the Correct Elements

The selector :not(:open) by itself can match many elements that do not support an open state. Combine it with an element selector such as details or dialog.

Alternative for Details

details:not([open]) {
  background-color: #f5f5f5;
}

For details elements, the absence of the open attribute identifies the collapsed state.

Open State and HTML Attributes

The :open pseudo-class represents an element's current open state. For some elements, that state is also reflected by an HTML attribute.

Details Open Attribute

<details open>
  <summary>Details</summary>
  <p>Expanded content</p>
</details>

The open attribute indicates that the details element is expanded.

Attribute Selector

details[open] {
  background-color: #eaf6fc;
}

For details elements, details[open] and details:open identify the expanded state.

Dialog Open Attribute

dialog[open] {
  border-color: #006699;
}

The open attribute is present while a dialog is open. However, an attribute selector alone does not distinguish between modal and non-modal dialogs.

Select Controls

A native select control does not use an HTML open attribute to indicate that its picker is displayed. The :open pseudo-class provides a state-based selector for supported picker controls.

Boolean Attributes

The open attribute on details and dialog elements is Boolean. Its presence indicates the open state, even when written as open="false". Remove the attribute to represent the closed state.

Related Pseudo-Classes

Several CSS pseudo-classes represent interactive states or conditions related to open elements.

Comparison

Selector Matching Behavior
:openMatches supported elements while they are open.
:not(:open)Matches elements that do not currently match :open.
:modalMatches elements in a modal state, such as a modal dialog.
:popover-openMatches a popover element while it is showing.
:focusMatches an element that currently has focus.
:focus-withinMatches an element that has focus or contains a focused descendant.
[open]Matches elements with an open attribute, regardless of element type.

Open vs. Modal

dialog:open {
  border: 2px solid #006699;
}
dialog:modal {
  box-shadow: 0 8px 24px rgb(0 0 0 / 20%);
}

The first rule applies to open dialogs. The second applies only when the dialog is modal.

Open vs. Popover Open

details:open {
  background-color: #eaf6fc;
}
[popover]:popover-open {
  border-color: #006699;
}

Use :open for supported open-state elements and :popover-open for elements currently displayed as popovers.

:open Specificity

The :open pseudo-class contributes a specificity of 0-1-0, like other standard pseudo-classes.

Specificity Examples

Selector Specificity
:open0-1-0
details:open0-1-1
.panel:open0-2-0
.content details:open0-2-1
#settings dialog:open1-1-1
details:not(:open)0-1-1

Specificity Example

details {
  border-color: #ccc;
}
details:open {
  border-color: #006699;
}

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

Attribute Selector Comparison

For details elements, details:open and details[open] have the same specificity of 0-1-1.

Practical Uses

The :open pseudo-class is useful for providing visual feedback when users expand or open interactive elements.

Expanded Details Panel

details:open {
  border-color: #006699;
  background-color: #eaf6fc;
}

Highlights a disclosure panel while its content is expanded.

Expanded Summary

details:open > summary {
  color: #006699;
  font-weight: bold;
}

Changes the summary appearance when its details element is open.

Open Dialog

dialog:open {
  border: 2px solid #006699;
  border-radius: 6px;
}

Applies styling to a dialog while it is displayed.

Open Select Picker

select:open {
  outline: 2px solid #006699;
}

Provides an open-state indicator for supported select controls.

Disclosure Icon

details > summary::after {
  content: "+";
  float: right;
}
details:open > summary::after {
  content: "-";
}

Changes a decorative symbol when the details element expands. The native summary marker may also need styling if a custom disclosure indicator is used.

Limitations

The :open pseudo-class applies only to elements with a supported open state.

Not a General Expanded-State Selector

An ordinary div or button does not match :open simply because JavaScript displays additional content.

Not Equivalent to aria-expanded

The aria-expanded attribute communicates an expanded or collapsed state to assistive technologies. It does not make an arbitrary element match :open.

Popover State Is Separate

Use :popover-open to select a displayed popover. Do not assume a popover matches :open.

Select Control Differences

Native select picker behavior and styling can vary between browsers and operating systems.

Not Based on CSS Visibility

Properties such as display, visibility, and opacity do not independently determine whether an element matches :open.

Browser Compatibility

The :open pseudo-class is newer than traditional attribute selectors such as details[open]. Older browsers may require alternative selectors for supported elements.

Best Practices

  • Use :open to style supported elements while they are open.
  • Combine it with element selectors such as details, dialog, or select.
  • Use details:open to highlight expanded disclosure content.
  • Use dialog:modal when styling should apply only to modal dialogs.
  • Use :popover-open for displayed popovers.
  • Do not confuse :open with the aria-expanded attribute.
  • Provide visible state indicators without relying on color alone.
  • Preserve keyboard accessibility and native interaction behavior.
  • Test native select controls across supported browsers and operating systems.
  • Use [open] as a compatibility alternative for details and dialog elements when appropriate.

:open Example

This example uses two details elements to demonstrate the :open pseudo-class. The first panel starts expanded, while the second starts collapsed. Opening or closing either panel changes its border, background, and summary text automatically.

HTML

<div class="open-demo">
  <details open>
    <summary>HTML Information</summary>
    <p>HTML defines the structure of a web page.</p>
  </details>
  <details>
    <summary>CSS Information</summary>
    <p>CSS controls the appearance of HTML elements.</p>
  </details>
</div>

CSS

.open-demo details {
  padding: 12px;
  margin-bottom: 10px;
  border: 2px solid #ccc;
  background-color: #f5f5f5;
}
.open-demo summary {
  cursor: pointer;
  font-weight: bold;
}
.open-demo details p {
  margin: 10px 0 0;
}
.open-demo details:open {
  border-color: #006699;
  background-color: #eaf6fc;
}
.open-demo details:open > summary {
  color: #006699;
}

Browser Result

Play in Editor

Note: HTML Information begins expanded and receives the blue styling. CSS Information starts collapsed and uses the standard gray styling. Click either summary to change its state.

Browser Support

Baseline: Newly available. The :open pseudo-class is supported in recent versions of major browsers. Older versions may not recognize it, and support for native select controls can vary.

For current compatibility information, visit Can I Use? and search for :open.

Compatibility Alternative

details[open] {
  border-color: #006699;
}
details:open {
  background-color: #eaf6fc;
}

The attribute selector provides established support for styling expanded details elements, while :open provides the newer state-based selector.

Specifications

The :open pseudo-class is defined in CSS Selectors Level 4 as an element-state pseudo-class. It matches elements with an open state while that state is active.

Selectors Level 4 - Open-State Pseudo-Class