Author: Karsten Biedermann
Url: https://medium.com/@karstenbiedermann/the-css-if-function-has-arrived-152115ab2115
Date Published: September 3, 2025
Content: The CSS if() Function Has Arrived!
The CSS if() Function Has Arrived!
Imagine being able to set CSS properties directly based on conditions — without JavaScript, without preprocessors, without workarounds. With the new if() function in CSS, this is now a reality. The CSS if() function officially shipped in Chrome 137.
For years, we’ve relied on workarounds: JavaScript toggle classes, CSS preprocessor mixins, or endless media query blocks. The if() function puts an end to all that, bringing conditional logic directly into CSS — elegant, performant, and declarative.
property: if(
condition-1: value-1;
condition-2: value-2;
condition-3: value-3;
else: default-value
);
The function checks conditions sequentially and applies the first matching value. If no condition matches, the else value is used — exactly as you’d expect from programming languages, but now in pure CSS.
The three capabilities of the if() function
With style(), you can react to CSS Custom Properties:
.card {
--status: attr(data-status type(<custom-ident>));
border-color: if(
style(--status: pending): royalblue;
style(--status: complete): seagreen;
style(--status: error): crimson;
else: gray
);
}
A single data-status attribute in HTML now controls the entire styling — no more utility classes needed!
Forget nested media query blocks. With media(), you define responsive values inline:
h1 {
font-size: if(
media(width >= 1200px): 3rem;
media(width >= 768px): 2.5rem;
media(width >= 480px): 2rem;
else: 1.75rem
);
Gone are the days of random fallback strategies and hoping things work 😬. With supports(), you check browser features directly in the property:
.element {
border-color: if(
supports(color: lch(0 0 0)): lch(50% 100 150);
supports(color: lab(0 0 0)): lab(50 100 -50);
else: rgb(200, 100, 50)
);
}
Real-world use cases
body {
--theme: "dark"; /* Toggle via JavaScript or User Preference */
background: if(
style(--theme: "dark"): #1a1a1a;
else: white
);
color: if(
style(--theme: "dark"): #e4e4e4;
else: #333
);
}
.alert {
--type: attr(data-type type(<custom-ident>));
background: if(
style(--type: success): #d4edda;
style(--type: warning): #fff3cd;
style(--type: danger): #f8d7da;
style(--type: info): #d1ecf1;
else: #f8f9fa
);
border-left: 4px solid if(
style(--type: success): #28a745;
style(--type: warning): #ffc107;
style(--type: danger): #dc3545;
style(--type: info): #17a2b8;
else: #6c757d
);
}
.container {
width: if(
media(width >= 1400px): 1320px;
media(width >= 1200px): 1140px;
media(width >= 992px): 960px;
media(width >= 768px): 720px;
media(width >= 576px): 540px;
else: 100%
);
padding-inline: if(
media(width >= 768px): 2rem;
else: 1rem
);
}
.element {
/* With the new light-dark() function */
color: if(
style(--high-contrast: true): black;
else: light-dark(#333, #e4e4e4)
);
/* With CSS Custom Functions (@function) */
padding: if(
style(--spacing: loose): --spacing-function(2);
style(--spacing: tight): --spacing-function(0.5);
else: --spacing-function(1)
);
}
Browser support
As of August 2025:
Since support is still growing, you can use this pattern:
.button {
/* Fallback for all browsers */
padding: 1rem 2rem;
background: #007bff;
/* Modern browsers automatically override */
padding: if(
style(--size: small): 0.5rem 1rem;
style(--size: large): 1.5rem 3rem;
else: 1rem 2rem
);
background: if(
style(--variant: primary): #007bff;
style(--variant: success): #28a745;
style(--variant: danger): #dc3545;
else: #6c757d
);
}
What the future holds
The CSS Working Group is already working on extensions: