CSS 44 💻 scripting, update and video-dynamic-range media features
These three media features let you adapt styles based on JavaScript availability, display refresh capability, and HDR video support.
Overview of Features
| Feature | Description | Values |
|---|---|---|
scripting | Detects JavaScript availability | none, initial-only, enabled |
update | How often the display can update | none, slow, fast |
video-dynamic-range | Dynamic range of the video plane | standard, high |
1. scripting
The scripting media feature detects whether JavaScript is available in the browser.
@media (scripting: enabled) {
.enabled {
color: red;
font-weight: bold;
}
}
Values
| Value | Description |
|---|---|
none | Scripting is not available (JavaScript disabled) |
initial-only | Scripting available only during initial page load |
enabled | Scripting is fully supported (default) |
When to Use
- Provide fallbacks for users with JavaScript disabled
- Show/hide JavaScript-dependent UI elements
- Style progressive enhancement layers
- Display noscript alternatives with CSS instead of
<noscript>
How Users Disable JavaScript
- Chrome: Settings → Privacy → Site Settings → JavaScript → Blocked
- Firefox: about:config →
javascript.enabled→ false - Safari: Develop → Disable JavaScript
- Brave: Shields → Scripts blocked
Key Points:
enabledis the default in modern browsersnonemeans no JavaScript at all — plan for progressive enhancementinitial-onlyis rare (some email clients, print preview)- Use this to style fallback content instead of relying on
<noscript>
2. update
The update media feature checks how frequently the device can update rendered content — essentially, its refresh capability.
@media (update: fast) {
p {
animation: slide 1s infinite alternate;
}
}
Values
| Value | Description | Device Example |
|---|---|---|
none | Content cannot be updated after rendering | Print, e-ink (static) |
slow | Updates are possible but not fast enough for smooth animation | E-ink readers, some low-power devices |
fast | Content can be updated quickly for smooth animation | Modern screens (60Hz+) |
When to Use
| Update Value | Recommendation |
|---|---|
none | Disable all animations and transitions |
slow | Use slow, infrequent animations only |
fast | Enable smooth animations and transitions |
Key Points:
fastis the default on modern displaysslowdevices (e-ink) can’t handle smooth animationnonemeans the content is static after rendering- Use this to conditionally enable animations based on device capability
Practical Example
/* No animation on static devices */
@media (update: none) {
p {
animation: none;
}
}
/* Slow animation on e-ink */
@media (update: slow) {
p {
animation: slide 5s infinite alternate;
}
}
/* Fast animation on modern screens */
@media (update: fast) {
p {
animation: slide 1s infinite alternate;
}
}
3. video-dynamic-range
The video-dynamic-range media feature queries the dynamic range of the video plane — specifically for HDR video content.
@media (video-dynamic-range: high) {
h1 {
color: blue;
}
}
Values
| Value | Description |
|---|---|
standard | Standard Dynamic Range (SDR) — most displays |
high | High Dynamic Range (HDR) — supports HDR video |
How It Differs from dynamic-range
| Feature | Target |
|---|---|
dynamic-range | The whole output device (display) |
video-dynamic-range | The video plane specifically |
Key Points:
video-dynamic-rangeis for video content (HDR video playback)dynamic-rangeis for the display itself- A device may support HDR video but not have a high-dynamic-range display
- Limited browser support — always provide a
standardfallback
HDR Requirements
| Requirement | Minimum |
|---|---|
| Color depth | > 24-bit |
| Peak brightness | High (1000+ nits) |
| Contrast ratio | High |
Complete Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>scripting, update, and video-dynamic-range</title>
<style>
*, *::before, *::after {
box-sizing: border-box;
}
:root {
--bg-primary: #ffffff;
--bg-secondary: #f8f9fa;
--bg-tertiary: #e9ecef;
--text-primary: #212529;
--text-secondary: #6c757d;
--accent: #007bff;
--border: #dee2e6;
--shadow: rgba(0, 0, 0, 0.1);
}
@media (prefers-color-scheme: dark) {
:root {
--bg-primary: #1a1a1a;
--bg-secondary: #0d0d0d;
--bg-tertiary: #2d2d2d;
--text-primary: #f8f9fa;
--text-secondary: #adb5bd;
--accent: #4dabf7;
--border: #444;
--shadow: rgba(0, 0, 0, 0.5);
}
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
padding: 20px;
background: var(--bg-secondary);
color: var(--text-primary);
max-width: 1200px;
margin: 0 auto;
line-height: 1.6;
transition: background 0.3s, color 0.3s;
}
h1 {
color: var(--accent);
border-bottom: 3px solid var(--accent);
padding-bottom: 10px;
}
h2 {
color: var(--accent);
border-left: 4px solid var(--accent);
padding-left: 15px;
margin-top: 30px;
}
h3 {
color: var(--text-primary);
margin-top: 20px;
}
section {
background: var(--bg-primary);
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px var(--shadow);
margin: 20px 0;
transition: all 0.3s;
}
.code-block {
background: #1e1e1e;
color: #d4d4d4;
padding: 15px;
border-radius: 8px;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 0.9rem;
line-height: 1.8;
margin: 10px 0;
}
.reference-table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
}
.reference-table th,
.reference-table td {
padding: 10px;
border: 1px solid var(--border);
text-align: left;
}
.reference-table th {
background: var(--accent);
color: white;
}
.reference-table tr:nth-child(even) {
background: var(--bg-tertiary);
}
.note {
font-size: 0.9rem;
color: var(--text-secondary);
margin-top: 5px;
}
.highlight {
background: #ffc107;
color: #333;
padding: 2px 6px;
border-radius: 4px;
font-weight: bold;
}
/* ====== SCRIPTING DEMO ====== */
.scripting-demo {
padding: 20px;
border-radius: 8px;
margin: 15px 0;
border: 2px solid var(--border);
background: var(--bg-tertiary);
text-align: center;
font-weight: bold;
font-size: 1.1rem;
transition: all 0.3s;
}
/* No scripting */
@media (scripting: none) {
.scripting-demo {
background: #dc3545;
color: white;
border-color: #a71d2a;
}
.scripting-demo::after {
content: " (scripting disabled)";
font-weight: normal;
font-size: 0.85rem;
}
}
/* Initial-only scripting */
@media (scripting: initial-only) {
.scripting-demo {
background: #ffc107;
color: #333;
border-color: #d39e00;
}
.scripting-demo::after {
content: " (scripting available only on initial load)";
font-weight: normal;
font-size: 0.85rem;
}
}
/* Full scripting */
@media (scripting: enabled) {
.scripting-demo {
background: #28a745;
color: white;
border-color: #1e7e34;
}
.scripting-demo::after {
content: " (scripting fully enabled)";
font-weight: normal;
font-size: 0.85rem;
}
}
/* ====== UPDATE DEMO ====== */
.update-demo {
padding: 20px;
border-radius: 8px;
margin: 15px 0;
border: 2px solid var(--border);
background: var(--bg-tertiary);
text-align: center;
font-weight: bold;
font-size: 1.1rem;
transition: all 0.3s;
overflow: hidden;
position: relative;
min-height: 80px;
display: flex;
align-items: center;
justify-content: center;
}
@keyframes slide {
from {
transform: translateX(-100%);
}
to {
transform: translateX(100%);
}
}
.update-demo .animated-content {
display: inline-block;
white-space: nowrap;
}
/* No update capability */
@media (update: none) {
.update-demo {
background: #dc3545;
color: white;
border-color: #a71d2a;
}
.update-demo .animated-content {
animation: none;
}
.update-demo::after {
content: " (no update capability — animation disabled)";
font-weight: normal;
font-size: 0.85rem;
}
}
/* Slow update */
@media (update: slow) {
.update-demo {
background: #ffc107;
color: #333;
border-color: #d39e00;
}
.update-demo .animated-content {
animation: slide 5s infinite alternate;
}
.update-demo::after {
content: " (slow update — slow animation)";
font-weight: normal;
font-size: 0.85rem;
}
}
/* Fast update */
@media (update: fast) {
.update-demo {
background: #28a745;
color: white;
border-color: #1e7e34;
}
.update-demo .animated-content {
animation: slide 1s infinite alternate;
}
.update-demo::after {
content: " (fast update — smooth animation)";
font-weight: normal;
font-size: 0.85rem;
}
}
/* ====== VIDEO-DYNAMIC-RANGE DEMO ====== */
.hdr-demo {
border-radius: 12px;
overflow: hidden;
margin: 15px 0;
}
.hdr-demo .video-container {
width: 100%;
height: 250px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
font-weight: bold;
color: white;
text-shadow: 0 2px 10px rgba(0,0,0,0.3);
transition: all 0.3s;
/* Standard dynamic range */
background: linear-gradient(135deg, #007bff, #6c5ce7);
}
/* High dynamic range video */
@media (video-dynamic-range: high) {
.hdr-demo .video-container {
background: linear-gradient(135deg,
oklch(69% 0.27 240),
oklch(69% 0.27 300),
oklch(69% 0.27 30));
box-shadow: 0 0 40px rgba(108, 92, 231, 0.5);
}
.hdr-demo .video-container::after {
content: " (HDR video enhanced ✨)";
font-size: 1rem;
font-weight: normal;
display: block;
margin-top: 5px;
}
}
/* ====== DETECTION CARDS ====== */
.detection-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin: 20px 0;
}
.detection-card {
padding: 15px;
border-radius: 8px;
text-align: center;
border: 2px solid var(--border);
background: var(--bg-tertiary);
transition: all 0.3s;
}
.detection-card .label {
font-size: 0.85rem;
color: var(--text-secondary);
display: block;
margin-bottom: 5px;
}
.detection-card .value {
font-size: 1.1rem;
font-weight: bold;
color: var(--accent);
}
.detection-card.active {
border-color: var(--accent);
background: var(--bg-primary);
}
/* ====== LIVE INDICATOR ====== */
.live-indicator {
position: fixed;
bottom: 20px;
right: 20px;
background: var(--accent);
color: white;
padding: 12px 20px;
border-radius: 50px;
font-weight: bold;
font-size: 0.85rem;
box-shadow: 0 4px 15px var(--shadow);
z-index: 1000;
transition: all 0.3s;
display: flex;
flex-direction: column;
gap: 3px;
}
.live-indicator .detail {
font-size: 0.75rem;
opacity: 0.9;
}
/* ====== NOSCRIPT FALLBACK ====== */
.noscript-message {
display: none;
padding: 15px;
background: #f8d7da;
border: 2px solid #dc3545;
border-radius: 8px;
color: #721c24;
margin: 15px 0;
font-weight: bold;
}
@media (scripting: none) {
.noscript-message {
display: block;
}
}
/* ====== TIPS ====== */
.tip-box {
padding: 15px;
border-radius: 8px;
margin: 10px 0;
border-left: 4px solid var(--accent);
background: var(--bg-tertiary);
}
.tip-box.success { border-left-color: #28a745; }
.tip-box.warning { border-left-color: #ffc107; }
.tip-box.danger { border-left-color: #dc3545; }
</style>
</head>
<body>
<h1>scripting, update, and video-dynamic-range</h1>
<!-- ====== NOSCRIPT MESSAGE ====== -->
<div class="noscript-message">
⚠️ JavaScript is disabled in your browser. Some features may not work correctly.
</div>
<!-- ====== 1. SCRIPTING DEMO ====== -->
<section>
<h2>1. scripting</h2>
<p>Detects whether <strong>JavaScript is available</strong> in the browser.</p>
<div class="scripting-demo">
Scripting Detection
</div>
<div class="code-block">
/* No scripting */
@media (scripting: none) {
.demo {
background: #dc3545;
}
}
/* Initial-only scripting */
@media (scripting: initial-only) {
.demo {
background: #ffc107;
}
}
/* Full scripting */
@media (scripting: enabled) {
.demo {
background: #28a745;
}
}
</div>
<p class="note">Use this to style fallback content for users with JavaScript disabled.</p>
</section>
<!-- ====== 2. UPDATE DEMO ====== -->
<section>
<h2>2. update</h2>
<p>Detects how <strong>frequently the display can update</strong> content.</p>
<div class="update-demo">
<span class="animated-content">🚀 Animation Speed Demo</span>
</div>
<div class="code-block">
/* No update capability — disable animation */
@media (update: none) {
.demo .animated-content {
animation: none;
}
}
/* Slow update — slow animation */
@media (update: slow) {
.demo .animated-content {
animation: slide 5s infinite alternate;
}
}
/* Fast update — smooth animation */
@media (update: fast) {
.demo .animated-content {
animation: slide 1s infinite alternate;
}
}
</div>
<p class="note">E-ink displays have <code>update: slow</code> — animations should be infrequent. Print has <code>update: none</code> — no animation at all.</p>
</section>
<!-- ====== 3. VIDEO-DYNAMIC-RANGE DEMO ====== -->
<section>
<h2>3. video-dynamic-range</h2>
<p>Detects the <strong>dynamic range of the video plane</strong> — specifically for HDR video.</p>
<div class="hdr-demo">
<div class="video-container">
🎬 HDR Video Demo
</div>
</div>
<div class="code-block">
/* Standard dynamic range video */
@media (video-dynamic-range: standard) {
.video {
/* SDR styles */
}
}
/* High dynamic range video */
@media (video-dynamic-range: high) {
.video {
background: linear-gradient(135deg,
oklch(69% 0.27 240),
oklch(69% 0.27 300));
}
}
</div>
<div class="tip-box warning">
<strong>⚠️ Limited Availability:</strong>
<code>video-dynamic-range</code> has limited browser support. Always provide a <code>standard</code> fallback.
</div>
</section>
<!-- ====== 4. DETECTION SUMMARY ====== -->
<section>
<h2>4. Your Device's Capabilities</h2>
<p>Below is a live detection of your device's capabilities.</p>
<div class="detection-grid">
<div class="detection-card" id="scripting-none">
<span class="label">scripting: none</span>
<span class="value" id="scripting-none-value">Detecting...</span>
</div>
<div class="detection-card" id="scripting-initial">
<span class="label">scripting: initial-only</span>
<span class="value" id="scripting-initial-value">Detecting...</span>
</div>
<div class="detection-card" id="scripting-enabled">
<span class="label">scripting: enabled</span>
<span class="value" id="scripting-enabled-value">Detecting...</span>
</div>
<div class="detection-card" id="update-none">
<span class="label">update: none</span>
<span class="value" id="update-none-value">Detecting...</span>
</div>
<div class="detection-card" id="update-slow">
<span class="label">update: slow</span>
<span class="value" id="update-slow-value">Detecting...</span>
</div>
<div class="detection-card" id="update-fast">
<span class="label">update: fast</span>
<span class="value" id="update-fast-value">Detecting...</span>
</div>
<div class="detection-card" id="vdr-standard">
<span class="label">video-dynamic-range: standard</span>
<span class="value" id="vdr-standard-value">Detecting...</span>
</div>
<div class="detection-card" id="vdr-high">
<span class="label">video-dynamic-range: high</span>
<span class="value" id="vdr-high-value">Detecting...</span>
</div>
</div>
<div class="code-block">
/* Detect scripting */
@media (scripting: none) { /* No JavaScript */ }
@media (scripting: initial-only) { /* Initial load only */ }
@media (scripting: enabled) { /* Full JavaScript */ }
/* Detect update capability */
@media (update: none) { /* No update — static */ }
@media (update: slow) { /* Slow update — e-ink */ }
@media (update: fast) { /* Fast update — modern */ }
/* Detect video dynamic range */
@media (video-dynamic-range: standard) { /* SDR video */ }
@media (video-dynamic-range: high) { /* HDR video */ }
</div>
</section>
<!-- ====== 5. REFERENCE TABLES ====== -->
<section>
<h2>5. Reference Tables</h2>
<h3>scripting Values</h3>
<table class="reference-table">
<tr>
<th>Value</th>
<th>Description</th>
<th>Device Example</th>
</tr>
<tr>
<td><code>none</code></td>
<td>Scripting not available</td>
<td>JavaScript disabled, some email clients</td>
</tr>
<tr>
<td><code>initial-only</code></td>
<td>Scripting only during initial load</td>
<td>Print preview, some email clients</td>
</tr>
<tr>
<td><code>enabled</code></td>
<td>Scripting fully supported (default)</td>
<td>Modern browsers</td>
</tr>
</table>
<h3>update Values</h3>
<table class="reference-table">
<tr>
<th>Value</th>
<th>Description</th>
<th>Device Example</th>
</tr>
<tr>
<td><code>none</code></td>
<td>Content cannot be updated after rendering</td>
<td>Print, static e-ink</td>
</tr>
<tr>
<td><code>slow</code></td>
<td>Updates possible but not smooth</td>
<td>E-ink readers, low-power devices</td>
</tr>
<tr>
<td><code>fast</code></td>
<td>Content updates quickly (default)</td>
<td>Modern screens (60Hz+)</td>
</tr>
</table>
<h3>video-dynamic-range Values</h3>
<table class="reference-table">
<tr>
<th>Value</th>
<th>Description</th>
<th>Requirements</th>
</tr>
<tr>
<td><code>standard</code></td>
<td>Standard Dynamic Range (SDR)</td>
<td>Typical displays</td>
</tr>
<tr>
<td><code>high</code></td>
<td>High Dynamic Range (HDR)</td>
<td>Color depth > 24-bit, high brightness, high contrast</td>
</tr>
</table>
<h3>dynamic-range vs video-dynamic-range</h3>
<table class="reference-table">
<tr>
<th>Feature</th>
<th>Target</th>
</tr>
<tr>
<td><code>dynamic-range</code></td>
<td>The whole output device (display)</td>
</tr>
<tr>
<td><code>video-dynamic-range</code></td>
<td>The video plane specifically</td>
</tr>
</table>
</section>
<!-- ====== 6. BEST PRACTICES ====== -->
<section>
<h2>6. Best Practices</h2>
<div style="background: #d4edda; padding: 20px; border-radius: 8px; border-left: 4px solid #28a745;">
<h3 style="margin-top: 0; color: #155724;">✅ Do This:</h3>
<ul>
<li>Use <code>scripting</code> to style fallbacks for users with JavaScript disabled</li>
<li>Use <code>update</code> to conditionally enable animations based on device capability</li>
<li>Use <code>video-dynamic-range</code> to enhance HDR video playback</li>
<li>Always provide a working fallback for each feature</li>
<li>Test with JavaScript disabled in your browser</li>
<li>Test on e-ink devices or simulate slow updates</li>
</ul>
</div>
<div style="background: #f8d7da; padding: 20px; border-radius: 8px; border-left: 4px solid #dc3545; margin-top: 15px;">
<h3 style="margin-top: 0; color: #721c24;">❌ Don't Do This:</h3>
<ul>
<li>Don't rely solely on <code>scripting</code> for critical functionality</li>
<li>Don't use fast animations on <code>update: slow</code> devices</li>
<li>Don't use <code>video-dynamic-range</code> without a <code>standard</code> fallback</li>
<li>Don't confuse <code>dynamic-range</code> with <code>video-dynamic-range</code></li>
<li>Don't forget that <code>update: none</code> means no animation at all</li>
</ul>
</div>
</section>
<!-- ====== LIVE INDICATOR ====== -->
<div class="live-indicator" id="live-indicator">
<span id="indicator-scripting">Scripting: —</span>
<span class="detail" id="indicator-update">Update: —</span>
<span class="detail" id="indicator-vdr">Video DR: —</span>
</div>
<!-- ====== SCRIPT FOR DETECTION ====== -->
<script>
function updateIndicators() {
function setCard(card, isActive, activeText, inactiveText) {
const value = card.querySelector('.value');
if (isActive) {
value.textContent = activeText;
card.classList.add('active');
} else {
value.textContent = inactiveText;
card.classList.remove('active');
}
}
// Scripting detection
const scriptingNone = document.getElementById('scripting-none');
const scriptingInitial = document.getElementById('scripting-initial');
const scriptingEnabled = document.getElementById('scripting-enabled');
const isScriptingNone = window.matchMedia('(scripting: none)').matches;
const isScriptingInitial = window.matchMedia('(scripting: initial-only)').matches;
const isScriptingEnabled = window.matchMedia('(scripting: enabled)').matches;
setCard(scriptingNone, isScriptingNone, 'Active ✅', 'Not active');
setCard(scriptingInitial, isScriptingInitial, 'Active ✅', 'Not active');
setCard(scriptingEnabled, isScriptingEnabled, 'Active ✅', 'Not active');
// Update detection
const updateNone = document.getElementById('update-none');
const updateSlow = document.getElementById('update-slow');
const updateFast = document.getElementById('update-fast');
const isUpdateNone = window.matchMedia('(update: none)').matches;
const isUpdateSlow = window.matchMedia('(update: slow)').matches;
const isUpdateFast = window.matchMedia('(update: fast)').matches;
setCard(updateNone, isUpdateNone, 'Active ✅', 'Not active');
setCard(updateSlow, isUpdateSlow, 'Active ✅', 'Not active');
setCard(updateFast, isUpdateFast, 'Active ✅', 'Not active');
// Video dynamic range detection
const vdrStandard = document.getElementById('vdr-standard');
const vdrHigh = document.getElementById('vdr-high');
const isVdrStandard = window.matchMedia('(video-dynamic-range: standard)').matches;
const isVdrHigh = window.matchMedia('(video-dynamic-range: high)').matches;
setCard(vdrStandard, isVdrStandard, 'Active ✅', 'Not active');
setCard(vdrHigh, isVdrHigh, 'Active ✅', 'Not active');
// Live indicator
const indicatorScripting = document.getElementById('indicator-scripting');
const indicatorUpdate = document.getElementById('indicator-update');
const indicatorVdr = document.getElementById('indicator-vdr');
const indicator = document.getElementById('live-indicator');
let scriptingText = 'Unknown';
if (isScriptingEnabled) scriptingText = 'Enabled ✅';
else if (isScriptingInitial) scriptingText = 'Initial only ⚠️';
else if (isScriptingNone) scriptingText = 'None ❌';
indicatorScripting.textContent = 'JS: ' + scriptingText;
let updateText = 'Unknown';
if (isUpdateFast) updateText = 'Fast ⚡';
else if (isUpdateSlow) updateText = 'Slow 🐌';
else if (isUpdateNone) updateText = 'None 🚫';
indicatorUpdate.textContent = 'Update: ' + updateText;
let vdrText = 'Unknown';
if (isVdrHigh) vdrText = 'HDR ✨';
else if (isVdrStandard) vdrText = 'SDR';
indicatorVdr.textContent = 'Video DR: ' + vdrText;
// Color indicator
if (isUpdateFast && isScriptingEnabled) {
indicator.style.background = '#28a745';
indicator.style.color = 'white';
} else if (isUpdateSlow || isScriptingNone) {
indicator.style.background = '#ffc107';
indicator.style.color = '#333';
} else {
indicator.style.background = '#007bff';
indicator.style.color = 'white';
}
}
window.addEventListener('load', updateIndicators);
// Listen for changes
window.matchMedia('(scripting: enabled)').addEventListener('change', updateIndicators);
window.matchMedia('(update: fast)').addEventListener('change', updateIndicators);
window.matchMedia('(video-dynamic-range: high)').addEventListener('change', updateIndicators);
updateIndicators();
</script>
</body>
</html>
Quick Reference
| Feature | Description | Values |
|---|---|---|
scripting | JavaScript availability | none, initial-only, enabled |
update | Display update capability | none, slow, fast |
video-dynamic-range | Dynamic range of video plane | standard, high |
scripting Values
| Value | Description | Device Example |
|---|---|---|
none | No scripting | JS disabled, some email clients |
initial-only | Scripting only on initial load | Print preview, some email clients |
enabled | Full scripting (default) | Modern browsers |
update Values
| Value | Description | Device Example |
|---|---|---|
none | Content is static after rendering | Print, static e-ink |
slow | Updates possible but not smooth | E-ink readers |
fast | Smooth updates (default) | Modern screens (60Hz+) |
video-dynamic-range Values
| Value | Description | Requirements |
|---|---|---|
standard | Standard Dynamic Range (SDR) | Typical displays |
high | High Dynamic Range (HDR) | Color depth > 24-bit, high brightness, high contrast |
Best Practices
✅ Do This:
/* Style fallbacks for no JavaScript */
@media (scripting: none) {
.js-only {
display: none;
}
.noscript-fallback {
display: block;
}
}
/* Conditionally enable animations */
@media (update: none) {
.animated {
animation: none;
}
}
@media (update: slow) {
.animated {
animation: slide 5s infinite alternate;
}
}
@media (update: fast) {
.animated {
animation: slide 1s infinite alternate;
}
}
/* Enhance HDR video */
@media (video-dynamic-range: high) {
.video {
background: linear-gradient(135deg, oklch(69% 0.27 240), oklch(69% 0.27 300));
}
}
❌ Don’t Do This:
/* Don't rely on JavaScript for critical functionality */
@media (scripting: enabled) {
.content {
display: block;
/* Content is hidden without JS! */
}
}
/* Don't use fast animations on slow-update devices */
@media (update: slow) {
.animated {
animation: slide 0.1s infinite; /* Will flicker terribly! */
}
}
/* Don't confuse dynamic-range with video-dynamic-range */
@media (video-dynamic-range: high) {
/* This is for video, not the whole display */
}
Pro Tip: scripting is essential for progressive enhancement — always provide a working fallback for users with JavaScript disabled. update is great for device-adaptive animations — e-ink readers can’t handle smooth animation, so use slow, infrequent transitions. video-dynamic-range is a specialized feature for HDR video content — it has limited browser support, so always provide a standard fallback. Remember: dynamic-range is for the display, while video-dynamic-range is for the video plane specifically!
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!