v150 · covered on mdn
Media element pseudo-classes
CSS pseudo-classes that match <audio> and <video> elements based on playback state — :playing, :paused, :buffering, :stalled, :seeking, :muted, and :volume-locked — enabling declarative styling of media controls without JavaScript. Chrome 150 ships these across desktop, Android, and WebView.
this API is documented on MDN
:playing — CSS — MDN Web Docsgendn doesn't duplicate APIs that MDN already covers. Each pseudo-class has its own MDN page: :paused, :buffering, :stalled, :muted. Chrome 150 is the first Chromium-based release to ship the full set.
quick example
/* Show a pause icon overlay while playing */
video:playing::after {
content: "⏸";
position: absolute;
inset: 0;
display: grid;
place-items: center;
font-size: 3rem;
opacity: 0;
transition: opacity 0.2s;
}
video:playing:hover::after { opacity: 1; }
/* Dim the video when buffering */
video:buffering {
filter: brightness(0.6);
}
/* Style muted controls differently */
.volume-btn:has(+ video:muted) {
color: var(--text-muted);
}
The pseudo-classes reflect live playback state — no addEventListener required. They compose naturally with other selectors, :has(), and CSS transitions.
pseudo-classes at a glance
:playing— element is actively playing (including when temporarily stalled):paused— element is paused or not yet started:buffering— playback has stalled temporarily waiting for data, but the element intends to play:stalled— playback has stopped because data has not arrived for a significant time:seeking— the media is seeking to a new position:muted— audio output is muted:volume-locked— the volume is locked by the user agent and cannot be changed by script