Show description
CSS if(): The Ultimate Guide
CSS if(): The Ultimate Guide
System Update: CSS Logic Module Installed
The Era ofConditional Styling
Logic without JavaScript. Responsiveness without media blocks. Welcome to the biggest shift in CSS history.
Enter The Lab
01. The Syntax Lab
Interact with the controls to see how style() queries transform the object in real-time.
IDLE
// Render Output
--STATUS (STATE LOGIC)
'idle'
'success'
'error'
'loading'
--SHAPE (GEOMETRY LOGIC)
'square'
'circle'
LIVE CSS LOGIC
.element {
background: if(
style(--status: 'success'): #00f3ff;
style(--status: 'error'): #ff0055;
else: #334155
);
border-radius: if(
style(--shape: 'circle'): 50%;
else: 12px
);
}
Three Ways to Use if()
1. Style Queries
The "React Prop" of CSS. Style elements based on the value of a Custom Property variable.
width: if(style(--full: true): 100%; else: 50%);
2. Inline Media
Define responsiveness directly on the property. No more jumping to the bottom of the file.
font-size: if(media(width < 600px): 14px; else: 18px);
3. Feature Supports
Progressively enhance your styles without massive @supports blocks wrapper.
color: if(supports(color: lch(0 0 0)): lch(...); else: #555);
02. Real-World Use Case
A component that restructures itself based on its width using if(media(...)).
SIMULATE WIDTH:
800px
Sarah Connor
Full Stack Developer
Building the resistance against bad CSS.
COMMIT STATUS
98% Green
LATEST DEPLOY
2m ago
Logic: if(media(width < 400px): flex-direction: column; ...)
DESIGNED FOR CHROME 137+ // FALLBACKS ACTIVE FOR LEGACY BROWSERS
CSS Specifications are subject to change.
CSS if(): The Ultimate Guide
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS if(): The Ultimate Guide</title>
<style>
/* * CORE SYSTEM VARIABLES
*/
:root {
--bg-deep: #030407;
--bg-grid: #0a0b10;
--accent-cyan: #00f3ff;
--accent-pink: #ff0055;
--accent-yellow: #ffcc00;
--accent-purple: #bc13fe;
--text-main: #ffffff;
--text-muted: #6b7280;
--glass-border: rgba(255, 255, 255, 0.08);
--glass-bg: rgba(15, 23, 42, 0.6);
--font-display: 'Segoe UI', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
}
/* * RESET & BASE
*/
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
background-color: var(--bg-deep);
background-image:
linear-gradient(rgba(0, 243, 255, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 243, 255, 0.03) 1px, transparent 1px);
background-size: 50px 50px;
color: var(--text-main);
font-family: var(--font-display);
overflow-x: hidden;
}
/* * UTILITIES & TYPOGRAPHY
*/
.container { max-width: 1200px; margin: 0 auto; padding: 0 1.5rem; }
.section { padding: 6rem 0; position: relative; }
h1, h2, h3 { font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; }
.gradient-text {
background: linear-gradient(135deg, #fff 0%, var(--text-muted) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.neon-cyan { color: var(--accent-cyan); text-shadow: 0 0 20px rgba(0, 243, 255, 0.4); }
.neon-pink { color: var(--accent-pink); text-shadow: 0 0 20px rgba(255, 0, 85, 0.4); }
.code-font { font-family: var(--font-mono); }
/* * UI COMPONENTS (GLASSMORPHISM)
*/
.glass-panel {
background: var(--glass-bg);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid var(--glass-border);
border-radius: 24px;
box-shadow: 0 20px 40px -10px rgba(0,0,0,0.5);
overflow: hidden;
}
.btn {
background: rgba(255,255,255,0.05);
border: 1px solid var(--glass-border);
color: #fff;
padding: 0.75rem 1.5rem;
border-radius: 8px;
cursor: pointer;
font-family: var(--font-mono);
font-size: 0.9rem;
transition: all 0.2s ease;
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.btn:hover { background: rgba(255,255,255,0.1); border-color: #fff; transform: translateY(-2px); }
.btn.active-cyan { border-color: var(--accent-cyan); background: rgba(0, 243, 255, 0.15); color: var(--accent-cyan); box-shadow: 0 0 15px rgba(0,243,255,0.2); }
.btn.active-pink { border-color: var(--accent-pink); background: rgba(255, 0, 85, 0.15); color: var(--accent-pink); box-shadow: 0 0 15px rgba(255,0,85,0.2); }
/* * HERO SECTION
*/
.hero {
min-height: 90vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
position: relative;
}
.hero-glow {
position: absolute;
width: 600px;
height: 600px;
background: radial-gradient(circle, rgba(0, 243, 255, 0.1) 0%, transparent 70%);
top: 50%; left: 50%;
transform: translate(-50%, -50%);
pointer-events: none;
z-index: -1;
}
.hero h1 { font-size: clamp(3.5rem, 8vw, 7rem); margin-bottom: 1.5rem; }
.hero p { font-size: 1.25rem; color: var(--text-muted); max-width: 600px; margin: 0 auto 3rem; }
/* * DEMO 1: THE SYNTAX LAB
*/
.lab-interface {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
align-items: stretch;
}
@media (max-width: 900px) { .lab-interface { grid-template-columns: 1fr; } }
.lab-visual {
min-height: 400px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
background: radial-gradient(circle at center, #1a202c 0%, #000 100%);
}
.lab-object {
/* Default CSS Variables */
--shape: 'circle';
--status: 'idle';
width: 150px;
height: 150px;
display: grid;
place-items: center;
font-weight: bold;
font-size: 1.2rem;
transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
position: relative;
z-index: 10;
/* * NATIVE CSS IF() LOGIC (For Chrome 137+) */
border-radius: if(style(--shape: 'circle'): 50%; else: 12px);
background: if(
style(--status: 'success'): var(--accent-cyan);
style(--status: 'error'): var(--accent-pink);
style(--status: 'loading'): var(--accent-yellow);
else: #334155
);
box-shadow: if(
style(--status: 'success'): 0 0 60px rgba(0, 243, 255, 0.3);
style(--status: 'error'): 0 0 60px rgba(255, 0, 85, 0.3);
else: 0 0 0 transparent
);
transform: if(
style(--status: 'loading'): scale(0.9) rotate(180deg);
else: scale(1) rotate(0deg)
);
/* * JS FALLBACKS (Injects values via style attribute for demo) */
border-radius: var(--fb-radius, 12px);
background: var(--fb-bg, #334155);
box-shadow: var(--fb-shadow, none);
transform: var(--fb-transform, none);
}
.lab-controls { padding: 2.5rem; }
.control-group { margin-bottom: 2rem; }
.control-label { display: block; font-family: var(--font-mono); color: var(--text-muted); margin-bottom: 0.8rem; font-size: 0.85rem; letter-spacing: 1px; text-transform: uppercase; }
/* * CODE BLOCK STYLING
*/
pre {
background: #000;
padding: 1.5rem;
border-radius: 12px;
overflow-x: auto;
border: 1px solid #333;
margin-top: 1rem;
}
code { font-family: var(--font-mono); font-size: 0.9rem; line-height: 1.5; }
.token-prop { color: #fff; }
.token-val { color: var(--accent-cyan); }
.token-kw { color: var(--accent-pink); }
.token-comment { color: #555; }
/* * DEMO 2: REAL WORLD USE CASE (Responsive Card)
*/
.use-case-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.profile-card {
/* This container simulates a component that might be in a sidebar OR main content */
container-type: inline-size;
padding: 2rem;
display: flex;
flex-direction: column;
gap: 1.5rem;
transition: all 0.3s ease;
}
.profile-header {
display: flex;
align-items: center;
gap: 1rem;
/* Responsive Logic: If container is wide, stack differently */
flex-direction: if(media(width < 400px): column; else: row);
text-align: if(media(width < 400px): center; else: left);
/* Fallback */
flex-direction: var(--fb-flex-dir, row);
text-align: var(--fb-align, left);
}
.avatar {
width: 80px; height: 80px;
border-radius: 50%;
background: linear-gradient(45deg, var(--accent-purple), var(--accent-cyan));
flex-shrink: 0;
}
.badge {
display: inline-block;
padding: 0.25rem 0.75rem;
background: rgba(255,255,255,0.1);
border-radius: 50px;
font-size: 0.75rem;
margin-top: 0.5rem;
}
/* * FOOTER
*/
footer {
border-top: 1px solid var(--glass-border);
padding: 4rem 0;
text-align: center;
color: var(--text-muted);
font-family: var(--font-mono);
font-size: 0.85rem;
}
</style>
</head>
<body>
<main class="container">
<!-- HERO -->
<section class="hero">
<div class="hero-glow"></div>
<div style="position: relative; z-index: 2;">
<div class="btn" style="margin-bottom: 2rem; border-radius: 50px; background: rgba(0,243,255,0.1); border: 1px solid var(--accent-cyan); color: var(--accent-cyan);">
System Update: CSS Logic Module Installed
</div>
<h1>The Era of<br><span class="neon-cyan">Conditional Styling</span></h1>
<p>Logic without JavaScript. Responsiveness without media blocks. <br>Welcome to the biggest shift in CSS history.</p>
<a href="#lab" class="btn active-cyan" style="padding: 1rem 2rem; font-size: 1.1rem;">Enter The Lab</a>
</div>
</section>
<!-- DEMO 1: THE LAB -->
<section id="lab" class="section">
<div style="margin-bottom: 3rem;">
<h2 class="neon-pink">01. The Syntax Lab</h2>
<p style="color: var(--text-muted);">Interact with the controls to see how <code>style()</code> queries transform the object in real-time.</p>
</div>
<div class="glass-panel lab-interface">
<!-- Visual Output -->
<div class="lab-visual">
<div class="lab-object" id="labObject">
<span id="objText">IDLE</span>
</div>
<div style="position: absolute; bottom: 20px; right: 20px; font-family: var(--font-mono); font-size: 0.8rem; color: #555;">
// Render Output
</div>
</div>
<!-- Controls -->
<div class="lab-controls">
<div class="control-group">
<span class="control-label">--STATUS (STATE LOGIC)</span>
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
<button class="btn active-cyan" onclick="updateLab('status', 'idle', this)">'idle'</button>
<button class="btn" onclick="updateLab('status', 'success', this)">'success'</button>
<button class="btn" onclick="updateLab('status', 'error', this)">'error'</button>
<button class="btn" onclick="updateLab('status', 'loading', this)">'loading'</button>
</div>
</div>
<div class="control-group">
<span class="control-label">--SHAPE (GEOMETRY LOGIC)</span>
<div style="display: flex; gap: 0.5rem;">
<button class="btn active-pink" onclick="updateLab('shape', 'square', this)">'square'</button>
<button class="btn" onclick="updateLab('shape', 'circle', this)">'circle'</button>
</div>
</div>
<!-- Live Code Preview -->
<div class="control-group" style="margin-bottom: 0;">
<span class="control-label">LIVE CSS LOGIC</span>
<pre><code id="codeBlock">.element {
background: <span class="token-kw">if</span>(
style(--status: 'success'): <span class="token-val">#00f3ff</span>;
style(--status: 'error'): <span class="token-val">#ff0055</span>;
<span class="token-kw">else</span>: <span class="token-val">#334155</span>
);
border-radius: <span class="token-kw">if</span>(
style(--shape: 'circle'): <span class="token-val">50%</span>;
<span class="token-kw">else</span>: <span class="token-val">12px</span>
);
}</code></pre>
</div>
</div>
</div>
</section>
<!-- INFO GRID -->
<section class="section">
<h2 class="gradient-text" style="text-align: center; margin-bottom: 4rem;">Three Ways to Use if()</h2>
<div class="use-case-grid">
<div class="glass-panel" style="padding: 2rem;">
<h3 class="neon-cyan" style="margin-bottom: 1rem;">1. Style Queries</h3>
<p style="color: var(--text-muted); margin-bottom: 1rem;">The "React Prop" of CSS. Style elements based on the value of a Custom Property variable.</p>
<code style="display: block; background: rgba(0,0,0,0.3); padding: 1rem; border-radius: 8px; color: var(--accent-cyan);">
width: if(style(--full: true): 100%; else: 50%);
</code>
</div>
<div class="glass-panel" style="padding: 2rem;">
<h3 class="neon-pink" style="margin-bottom: 1rem;">2. Inline Media</h3>
<p style="color: var(--text-muted); margin-bottom: 1rem;">Define responsiveness directly on the property. No more jumping to the bottom of the file.</p>
<code style="display: block; background: rgba(0,0,0,0.3); padding: 1rem; border-radius: 8px; color: var(--accent-pink);">
font-size: if(media(width < 600px): 14px; else: 18px);
</code>
</div>
<div class="glass-panel" style="padding: 2rem;">
<h3 class="neon-cyan" style="color: var(--accent-purple); margin-bottom: 1rem;">3. Feature Supports</h3>
<p style="color: var(--text-muted); margin-bottom: 1rem;">Progressively enhance your styles without massive @supports blocks wrapper.</p>
<code style="display: block; background: rgba(0,0,0,0.3); padding: 1rem; border-radius: 8px; color: var(--accent-purple);">
color: if(supports(color: lch(0 0 0)): lch(...); else: #555);
</code>
</div>
</div>
</section>
<!-- DEMO 2: REAL WORLD -->
<section class="section">
<div style="margin-bottom: 3rem; display: flex; justify-content: space-between; align-items: end; flex-wrap: wrap; gap: 1rem;">
<div>
<h2 class="gradient-text">02. Real-World Use Case</h2>
<p style="color: var(--text-muted);">A component that restructures itself based on its width using <code>if(media(...))</code>.</p>
</div>
<div style="display: flex; gap: 1rem; align-items: center;">
<span class="code-font" style="color: var(--text-muted); font-size: 0.9rem;">SIMULATE WIDTH:</span>
<input type="range" min="300" max="800" value="800" class="width-slider" oninput="updateCardWidth(this.value)" style="width: 200px;">
<span id="widthDisplay" class="code-font" style="color: var(--accent-cyan);">800px</span>
</div>
</div>
<div class="glass-panel" style="background: #000; padding: 3rem; display: flex; justify-content: center;">
<!-- The Responsive Component -->
<div id="demoCard" class="profile-card glass-panel" style="width: 800px; background: rgba(255,255,255,0.03);">
<div class="profile-header">
<div class="avatar"></div>
<div>
<h3 style="font-size: 1.5rem;">Sarah Connor</h3>
<span class="badge" style="color: var(--accent-cyan); border: 1px solid var(--accent-cyan);">Full Stack Developer</span>
<p style="color: var(--text-muted); margin-top: 0.5rem; font-size: 0.9rem;">Building the resistance against bad CSS.</p>
</div>
</div>
<div style="height: 1px; background: var(--glass-border);"></div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
<div>
<span class="code-font" style="color: #555; font-size: 0.8rem;">COMMIT STATUS</span>
<div style="color: var(--accent-cyan);">98% Green</div>
</div>
<div>
<span class="code-font" style="color: #555; font-size: 0.8rem;">LATEST DEPLOY</span>
<div style="color: #fff;">2m ago</div>
</div>
</div>
</div>
</div>
<div style="margin-top: 2rem; text-align: center;">
<p class="code-font" style="color: var(--text-muted);">
Logic: <span style="color: var(--accent-pink);">if(media(width < 400px): flex-direction: column; ...)</span>
</p>
</div>
</section>
<footer>
<p>DESIGNED FOR CHROME 137+ // FALLBACKS ACTIVE FOR LEGACY BROWSERS</p>
<p style="margin-top: 1rem; opacity: 0.5;">CSS Specifications are subject to change.</p>
</footer>
</main>
<script>
// * -----------------------------------------------------------------------
// * JAVASCRIPT FALLBACK ENGINE
// * -----------------------------------------------------------------------
// * This script ensures the visual demos work on current browsers
// * by simulating the logic that if() would handle natively.
// 1. LAB LOGIC
const labObj = document.getElementById('labObject');
const objText = document.getElementById('objText');
function updateLab(prop, value, btn) {
// Update UX
const siblings = btn.parentElement.querySelectorAll('.btn');
siblings.forEach(b => {
b.classList.remove('active-cyan', 'active-pink');
});
// Set active class based on value type for flair
if(value === 'error' || value === 'square') {
btn.classList.add('active-pink');
} else {
btn.classList.add('active-cyan');
}
// --- NATIVE WAY (Set the var) ---
labObj.style.setProperty(`--${prop}`, `'${value}'`);
// --- FALLBACK SIMULATION ---
if (prop === 'status') {
objText.innerText = value.toUpperCase();
const styles = {
'idle': { bg: '#334155', shadow: 'none', transform: 'none' },
'success': { bg: '#00f3ff', shadow: '0 0 60px rgba(0, 243, 255, 0.3)', transform: 'none' },
'error': { bg: '#ff0055', shadow: '0 0 60px rgba(255, 0, 85, 0.3)', transform: 'none' },
'loading': { bg: '#ffcc00', shadow: '0 0 30px rgba(255, 204, 0, 0.3)', transform: 'scale(0.9) rotate(180deg)' }
};
const s = styles[value];
labObj.style.setProperty('--fb-bg', s.bg);
labObj.style.setProperty('--fb-shadow', s.shadow);
labObj.style.setProperty('--fb-transform', s.transform);
}
if (prop === 'shape') {
const radius = value === 'circle' ? '50%' : '12px';
labObj.style.setProperty('--fb-radius', radius);
}
}
// 2. RESPONSIVE CARD LOGIC
const demoCard = document.getElementById('demoCard');
const widthDisplay = document.getElementById('widthDisplay');
const cardHeader = demoCard.querySelector('.profile-header');
function updateCardWidth(val) {
// Update Visuals
demoCard.style.width = `${val}px`;
widthDisplay.innerText = `${val}px`;
// --- NATIVE WAY ---
// The CSS inside the <style> block handles this if browser supports if()
// --- FALLBACK SIMULATION ---
// We manually check the width and apply styles to vars
if (val < 400) {
demoCard.style.setProperty('--fb-flex-dir', 'column');
demoCard.style.setProperty('--fb-align', 'center');
} else {
demoCard.style.setProperty('--fb-flex-dir', 'row');
demoCard.style.setProperty('--fb-align', 'left');
}
}
</script>
</body>
</html>