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 |
|---|---|
:stalled | Represents a media element stalled because expected media progress cannot continue. |
:buffering | Represents 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 |
|---|---|
:stalled | Represents stalled media progress. |
:seeking | Represents 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 |
|---|---|
:playing | Matches a media element in the playing state. |
:paused | Matches a media element in the paused state. |
:seeking | Matches a media element during seeking. |
:buffering | Matches a media element during buffering. |
:stalled | Matches a media element in the stalled state. |
:muted | Matches a media element whose audio output is muted. |
:volume-locked | Matches 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 |
|---|---|
stalled | Media data is unexpectedly unavailable while the browser is attempting to fetch it. |
waiting | Playback has stopped temporarily while waiting for data or another condition. |
progress | The browser has made progress fetching media data. |
canplay | The browser has enough data to begin playback, although interruptions may still occur. |
playing | Playback is ready to start or resume after being paused or delayed. |
error | An 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 |
|---|---|
:stalled | 0-1-0 |
video:stalled | 0-1-1 |
audio:stalled | 0-1-1 |
.media-player:stalled | 0-2-0 |
#demo-video:stalled | 1-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
:stalledfor 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
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.
