CSS :stalled Pseudo-Class

The CSS :stalled pseudo-class represents an audio or video element that is stalled because it cannot make the expected progress in obtaining or processing media data. It is intended to help developers provide visual feedback when media playback encounters a temporary interruption. Browser support is limited, so JavaScript media events are useful for providing a fallback.

:stalled Syntax

:stalled {
  property: value;
}

The :stalled pseudo-class is used with media elements to apply styles when the browser identifies a stalled media state.

Video Example

video:stalled {
  outline: 3px solid #b3261e;
}

Applies a red outline to a stalled video element in browsers that support the selector.

Audio Example

audio:stalled {
  opacity: 0.7;
}

Changes the appearance of an audio element while it matches the stalled state.

Combined Selector

video:stalled,
audio:stalled {
  outline: 3px solid #b3261e;
}

Applies the same stalled-state styling to both audio and video elements.

No Arguments

The pseudo-class is written as :stalled, without parentheses or arguments.

How :stalled Works

Media playback depends on the browser receiving and processing enough data to continue. A stalled condition occurs when the media resource cannot make the expected progress.

Normal Playback

During normal playback, the browser advances through the media timeline using available audio or video data.

Playback Interruption

If additional data becomes unavailable, the browser may be unable to continue playback normally.

Stalled State

When the media element enters a stalled state, a supporting browser can match the element using :stalled.

Recovery

If media data becomes available again, the browser may resume normal playback and the stalled condition can end.

Automatic CSS Matching

Where implemented, the pseudo-class responds to the browser's media state without requiring a developer to add or remove CSS classes.

Not Always a Permanent Error

A temporary stall does not necessarily mean the media file is invalid or that playback has permanently failed.

Media Elements

The :stalled pseudo-class is intended for HTML media elements, including audio and video.

Video Element

<video controls width="300">
  <source src="video.mp4" type="video/mp4">
  Your browser does not support the video element.
</video>

The video element can encounter a stalled condition if the browser cannot obtain the data needed for playback.

Audio Element

<audio controls>
  <source src="audio.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio>

Audio playback can also stall when the browser cannot obtain sufficient media data.

Streaming Media

Streaming media may encounter interruptions when network delivery cannot keep up with playback requirements.

Locally Available Media

Media that has already been fully downloaded is less likely to stall because of network delivery, although other playback problems may still occur.

Other Elements

Ordinary HTML elements such as <div>, <p>, and <button> do not represent stalled media playback.

What Causes Stalling?

Several conditions can prevent a browser from obtaining or processing media data as expected.

Slow Network Connection

A connection may not deliver media data quickly enough for continuous playback.

Interrupted Download

A temporary network interruption can prevent additional media data from arriving.

Server Delays

A media server may respond slowly or temporarily stop delivering data.

Streaming Problems

Live streams and segmented media delivery can experience interruptions or unavailable segments.

Playback Position Changes

Seeking to a position that has not been downloaded may require additional data before playback can continue.

Not Every Delay Is a Stall

Media can pause or wait for reasons unrelated to a stalled data transfer. Use the browser's media events and properties to distinguish conditions.

:stalled vs. :buffering

Stalling and buffering are related media conditions, but they do not describe exactly the same state.

Comparison

Pseudo-Class Matching Behavior
:stalledRepresents a media element stalled because expected media progress cannot continue.
:bufferingRepresents a media element temporarily buffering data needed for playback.

Stalled Styling

video:stalled {
  outline: 3px solid #b3261e;
}

Buffering Styling

video:buffering {
  outline: 3px solid #cc6600;
}

Possible Overlap

Buffering and stalled conditions can occur close together or overlap, depending on the media resource and browser behavior.

Different Feedback

Use buffering feedback for ordinary waiting periods and stalled feedback for interruptions that the browser identifies as stalled.

Browser Support

Both pseudo-classes have limited implementation support. JavaScript media events offer a more broadly compatible approach.

:stalled vs. :seeking

Seeking changes the playback position, while stalling indicates that media progress has been interrupted.

Comparison

Pseudo-Class Purpose
:stalledRepresents stalled media progress.
:seekingRepresents an active seek operation.

CSS Example

video:stalled {
  outline: 3px solid #b3261e;
}
video:seeking {
  outline: 3px solid #006699;
}

Seeking Can Trigger Waiting

After moving to a new position, the browser may need additional media data before playback can continue.

Stalling Without Seeking

Media playback can stall even when the playback position has not changed.

Separate States

Use the selector that describes the condition you want to communicate rather than treating both states as identical.

Other Playback States

CSS includes several media resource state pseudo-classes intended to represent different playback conditions.

Related Pseudo-Classes

Pseudo-Class Description
:playingMatches a media element in the playing state.
:pausedMatches a media element in the paused state.
:seekingMatches a media element during seeking.
:bufferingMatches a media element during buffering.
:stalledMatches a media element in the stalled state.
:mutedMatches a media element whose audio output is muted.
:volume-lockedMatches a media element whose volume cannot be changed by the user.

Multiple Matching States

Some media states can overlap. For example, a media element may be intended to play but be unable to progress because it is stalled.

CSS Cascade

If multiple matching selectors set the same property, the normal CSS cascade determines which declaration takes effect.

Support Varies

Not every media state pseudo-class is implemented in every browser. Check compatibility individually.

JavaScript and Stalled Media

JavaScript provides media events and properties that can help identify playback interruptions and display appropriate feedback.

Select a Video

const video = document.getElementById("demo-video");

Listen for a Stall

video.addEventListener("stalled", () => {
  console.log("Media data transfer stalled");
});

The stalled event fires when the browser is trying to obtain media data but the data is unexpectedly unavailable.

Listen for Waiting

video.addEventListener("waiting", () => {
  console.log("Waiting for playback data");
});

The waiting event indicates that playback has stopped temporarily while waiting for additional data or another condition.

Listen for Progress

video.addEventListener("progress", () => {
  console.log("Media download progress");
});

The progress event indicates progress in fetching media data.

Check Network State

console.log(video.networkState);

The networkState property reports the media element's current network activity state.

Check Ready State

console.log(video.readyState);

The readyState property reports how much media data is available for playback.

Event-Based Feedback

Media events can be used to add CSS classes and update status messages when the :stalled pseudo-class is unavailable.

Media Events

HTML media elements provide several events that help developers monitor loading, playback interruptions, and recovery.

Related Events

Event Description
stalledMedia data is unexpectedly unavailable while the browser is attempting to fetch it.
waitingPlayback has stopped temporarily while waiting for data or another condition.
progressThe browser has made progress fetching media data.
canplayThe browser has enough data to begin playback, although interruptions may still occur.
playingPlayback is ready to start or resume after being paused or delayed.
errorAn error occurred while loading or playing the media.

Stalled Event Example

video.addEventListener("stalled", () => {
  video.classList.add("is-stalled");
});

Recovery Example

video.addEventListener("playing", () => {
  video.classList.remove("is-stalled");
});

Removes the fallback class when playback resumes.

Important Distinction

The stalled event is a notification that a stall occurred. It does not provide a permanent Boolean property indicating whether the element is currently stalled.

Recovery Handling

Applications may need to handle several recovery events and changes in media readiness to keep their status messages accurate.

Fallback Styling

Because :stalled is not consistently supported, JavaScript can add a class when a stall occurs.

CSS Fallback

video:stalled,
video.is-stalled {
  outline: 3px solid #b3261e;
}

JavaScript Fallback

const video = document.querySelector("video");
video.addEventListener("stalled", () => {
  video.classList.add("is-stalled");
});
video.addEventListener("playing", () => {
  video.classList.remove("is-stalled");
});

The class provides a styling mechanism even when the browser does not implement the pseudo-class.

Additional Recovery Events

Depending on the player, it may be appropriate to clear the status when media becomes playable, playback resumes, or a new media resource is loaded.

Avoid Permanent Warning States

Do not leave a stalled warning visible after the player has recovered or the user has switched to another media resource.

Graceful Degradation

Unsupported pseudo-classes are ignored by the browser. An independently supported class selector can provide the same visual effect.

Visual Feedback

Visual feedback helps users understand that playback has been interrupted and may resume when media data becomes available.

Outline

video:stalled {
  outline: 3px solid #b3261e;
}

Highlights a stalled video element.

Opacity

video:stalled {
  opacity: 0.7;
}

Changes the video's appearance while stalled.

Container Styling

.media-player:has(video:stalled) {
  border: 2px solid #b3261e;
}

Styles a container when its video is stalled, in browsers supporting both selectors.

Status Message

.media-player .stall-message {
  display: none;
}
.media-player:has(video:stalled) .stall-message {
  display: block;
}

Displays a status message based on the media state in supporting browsers.

Accessible Feedback

Use JavaScript media events to update a visible status element when users need an accessible explanation of playback interruptions.

Avoid Distracting Effects

Simple outlines and text messages are generally preferable to continuous flashing or excessive animation.

:stalled Specificity

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

Specificity Examples

Selector Specificity
:stalled0-1-0
video:stalled0-1-1
audio:stalled0-1-1
.media-player:stalled0-2-0
#demo-video:stalled1-1-0
:where(video:stalled)0-0-0

Specificity Example

video {
  outline: 2px solid #ccc;
}
video:stalled {
  outline: 3px solid #b3261e;
}

When the video matches :stalled, the more specific rule takes precedence if other cascade factors are equal.

Fallback Selector

video:stalled,
video.is-stalled {
  outline-color: #b3261e;
}

Both selectors have a specificity of 0-1-1.

Practical Uses

The :stalled pseudo-class can provide feedback for media playback interruptions where supported.

Video Playback Warning

video:stalled {
  outline: 3px solid #b3261e;
}

Highlights a video when playback is stalled.

Audio Player Styling

audio:stalled {
  opacity: 0.7;
}

Changes the appearance of a stalled audio element.

Custom Player Border

.player:has(video:stalled) {
  border-color: #b3261e;
}

Highlights a custom player containing a stalled video.

JavaScript Status Class

.player.is-stalled {
  background-color: #fff3f3;
}

Allows a script to display a stalled-state appearance without depending on pseudo-class support.

Recovery Feedback

Use media events to remove stalled styling when playback resumes or the player becomes ready again.

Limitations

The :stalled pseudo-class has important limitations involving browser compatibility and media-state detection.

Limited Browser Support

The selector is not consistently implemented across major browsers.

Not Every Interruption Is a Stall

Media may stop temporarily because it is paused, seeking, buffering, or waiting for another reason.

Not a Permanent Error

A stalled condition does not necessarily mean that the media resource has failed permanently.

Media-Specific Selector

The pseudo-class is intended for media resource states rather than ordinary HTML elements.

No Automatic Recovery Message

CSS alone does not provide an accessible announcement that playback has recovered.

Browser Controls

Styling the video or audio element does not guarantee control over the appearance of the browser's built-in media controls.

Event Timing

Stalling and recovery can occur quickly. Event-based interfaces should account for changing media conditions.

Fallback State Tracking

A class added by a stalled event is an application-maintained indicator. It may not correspond exactly to the browser's internal stalled state.

Cross-Browser Testing

Test real media loading and interruption scenarios rather than assuming that every browser reports media conditions identically.

Best Practices

  • Use :stalled for media playback interruptions only where browser support is available.
  • Provide JavaScript event-based feedback when reliable cross-browser behavior is required.
  • Distinguish stalled playback from buffering, seeking, and ordinary pausing.
  • Do not describe every temporary interruption as a permanent playback error.
  • Use clear status text to explain playback interruptions.
  • Keep warning colors and visual effects consistent throughout the media player.
  • Remove fallback classes when the media player recovers or loads another resource.
  • Use accessible status updates when interruptions affect the user's experience.
  • Avoid flashing or distracting animations.
  • Test with actual audio or video resources and different network conditions.

:stalled Example

This example demonstrates stalled-state styling with an HTML video element. The CSS includes :stalled, while JavaScript provides a fallback class when a stalled event occurs. The Test Warning button simulates the visual warning so you can examine the styling without interrupting your network connection.

HTML

<div class="stalled-demo">
  <video id="demo-video" controls preload="metadata" width="280">
    <source src="movie-01.mp4" type="video/mp4">
    Your browser does not support the video element.
  </video>
  <p id="media-status" role="status" aria-live="polite">Ready</p>
  <button type="button" id="test-warning">Test Warning</button>
  <button type="button" id="reset-warning">Reset</button>
</div>

CSS

.stalled-demo video {
  display: block;
  max-width: 100%;
  outline: 3px solid transparent;
}
.stalled-demo video:stalled,
.stalled-demo video.is-stalled {
  outline-color: #b3261e;
}
.stalled-demo #media-status {
  margin: 10px 0;
  font-weight: bold;
}
.stalled-demo button {
  margin-right: 5px;
  padding: 8px 12px;
  cursor: pointer;
}

JavaScript

const video = document.getElementById("demo-video");
const status = document.getElementById("media-status");
const showWarning = message => {
  video.classList.add("is-stalled");
  status.textContent = message;
};
const clearWarning = () => {
  video.classList.remove("is-stalled");
  status.textContent = "Ready";
};
video.addEventListener("stalled", () => {
  showWarning("Media download stalled");
});
video.addEventListener("playing", clearWarning);
video.addEventListener("canplay", clearWarning);
document.getElementById("test-warning").addEventListener("click", () => {
  showWarning("Test warning - simulated stall");
});
document.getElementById("reset-warning").addEventListener("click", clearWarning);

Browser Result

Play in Editor

Note: The Test Warning button adds a fallback class to demonstrate the appearance of a stalled media element. It does not place the video into a real stalled state. The browser can also apply the styling through :stalled when supported.

Browser Support

Baseline: Limited availability. The :stalled pseudo-class is not consistently supported across major browsers. HTML media events such as stalled, waiting, and playing are more broadly supported.

For current compatibility information, visit Can I Use? and search for :stalled or media resource state pseudo-classes.

Specifications

The :stalled pseudo-class is defined in CSS Selectors Level 4 as a media resource state pseudo-class.

Selectors Level 4 - Media Resource State Pseudo-Classes