:state() CSS Pseudo Class
Description
The :state() pseudo-class is an experimental CSS selector used to style custom elements based on their internal state, as defined through the ElementInternals state API. It allows authors to apply styles when a custom element enters a named state - similar in spirit to how built-in form controls respond to states like :hover or :checked, but fully customizable.
Unlike traditional pseudo-classes, :state() is not automatically managed by the browser. Instead, the state must be explicitly defined and toggled via JavaScript using the element’s internal state map.
What :state() Does
The :state() pseudo-class matches a custom element when it has a specific named state set internally. This makes it possible to create semantic, reusable UI components that expose meaningful visual states without relying on attributes or classes.
Example syntax:
my-toggle:state(active) {
background-color: green;
}
In this example, the styles apply only when the custom element <my-toggle> is in the active state.
Defining a State (JavaScript)
States are defined using the ElementInternals.states API inside a custom element class:
class MyToggle extends HTMLElement {
constructor() {
super();
this._internals = this.attachInternals();
}
activate() {
this._internals.states.add("active");
}
deactivate() {
this._internals.states.delete("active");
}
}
customElements.define("my-toggle", MyToggle);
Once the "active" state is added, it can be targeted using :state() in CSS.
Example Usage
<my-toggle id="toggle"></my-toggle>
my-toggle:state(active) {
border: 2px solid green;
background: #e6ffe6;
}
document.getElementById("toggle").addEventListener("click", e => {
e.target.activate();
});
When to Use :state()
Use :state() when:
- You are building custom elements
- You want encapsulated, semantic state styling
- You want to avoid relying on class toggling or data attributes
- You need better integration with the browser’s styling model
Important Notes
:state()only works with custom elements, not standard HTML elements likebutton.- Browser support is currently limited and experimental, so it should be used cautiously in production.
- It is part of the evolving CSS Selectors Level 4 specification.
Syntax
:state(<custom identifier>) {
/* ... */
}
Values
- <custom identifier>The :state() pseudo-class takes as its argument a custom identifier that represents the state of the custom element to match.
Example
Browser Support
The following information will show you the current browser support for the CSS :state() pseudo class. Hover over a browser icon to see the version that first introduced support for this CSS psuedo class.
This psuedo class is supported by all modern browsers.
Desktop
Tablets & Mobile
Last updated by CSSPortal on: 31st December 2025
