CSS if() Function
The CSS if() function selects a property value based on whether a specified condition evaluates to true.
It provides conditional logic directly inside CSS declarations. Conditions can test custom property values, media features, or browser support for CSS features. The function can select an entire property value or part of a value without requiring JavaScript.
Syntax
if(condition: value)
if(condition: value; else: fallback)
if(condition1: value1; condition2: value2; else: fallback)
Each branch contains a condition followed by a colon and a value. Multiple branches are separated by semicolons.
For example:
.box {
color: if(style(--theme: dark): white; else: black);
}
This selects white text when the --theme custom property equals dark. Otherwise, it selects black.
Additional examples:
color: if(style(--theme: dark): white; else: black);
padding: if(media(width < 600px): 10px; else: 20px);
display: if(supports(display: grid): grid; else: block);
background-color: if(else: blue);
The final semicolon inside if() is optional.
The function returns the value associated with the first matching condition. If no condition matches and there is no else branch, the result is guaranteed-invalid.
Parameters
The if() function accepts an ordered list of conditional branches.
| Component | Description | Required |
|---|---|---|
condition |
A style, media, or feature support test, or the else keyword. |
For a useful conditional expression |
value |
The CSS value selected when the condition matches. | Normally |
else |
An unconditional branch commonly used as the final fallback. | No |
; |
Separates conditional branches. | Between branches |
The three main condition types are:
| Condition | Purpose | Example |
|---|---|---|
style() |
Tests a CSS property value, commonly a custom property. | style(--theme: dark) |
media() |
Tests a media type or media feature. | media(width < 600px) |
supports() |
Tests browser support for a CSS feature. | supports(display: grid) |
Unlike many CSS mathematical functions, if() does not require all returned values to have the same numeric type. Each selected value must instead be valid in its surrounding property or expression.
How It Works
The if() function evaluates conditions in the order they appear.
- The browser evaluates the first condition.
- If it is true, the associated value is selected.
- If it is false, evaluation continues to the next branch.
- The first matching branch determines the result.
- If no branch matches, an
elsebranch provides the fallback when present.
For example:
.message {
--status: warning;
color: if(
style(--status: success): green;
style(--status: warning): darkorange;
else: black
);
}
The first condition is false because --status is not success. The second condition matches, so the text becomes dark orange.
The else branch is not evaluated because an earlier condition has already matched.
Unlike an @media rule, a false condition does not cause the browser to skip the entire CSS declaration and return to an earlier declaration in the cascade.
Style Conditions
The style() condition tests the value of a CSS property on the element receiving the declaration.
For example:
.card {
--theme: dark;
background-color: if(
style(--theme: dark): #222;
else: #eee
);
color: if(
style(--theme: dark): white;
else: black
);
}
Because --theme equals dark, the card receives a dark background and white text.
Different elements can use different custom property values:
.card-light {
--theme: light;
}
.card-dark {
--theme: dark;
}
A shared CSS rule can then select different values for each element.
Unlike a container style query, an if() style condition can test a custom property on the element itself.
Style conditions are useful for themes, component variations, and reusable CSS designs.
Media Conditions
The media() condition selects values based on media queries.
For example:
.container {
padding: if(
media(width < 600px): 12px;
else: 30px
);
}
When the viewport is narrower than 600px, the padding is 12px. Otherwise, it is 30px.
Media conditions can also test user preferences:
.panel {
background-color: if(
media(prefers-color-scheme: dark): #222;
else: #fff
);
}
Another example uses print media:
.document {
color: if(
media(print): black;
else: #333
);
}
Media conditions are useful when a single property needs different values for different viewing environments.
For larger groups of responsive declarations, regular @media rules are often easier to organize.
Feature Support Conditions
The supports() condition selects a value based on whether the browser supports a specified CSS feature.
For example:
.layout {
display: if(
supports(display: grid): grid;
else: block
);
}
This selects grid when CSS Grid is supported, or block otherwise, provided the browser supports the if() function itself.
Another example tests a color function:
.heading {
color: if(
supports(color: oklch(60% 0.2 250)): oklch(60% 0.2 250);
else: #3366cc
);
}
The function selects the OKLCH color when supported and the hexadecimal color otherwise.
A supports() condition inside if() does not provide compatibility for browsers that do not understand if(). Those browsers still need a separate fallback declaration.
For broader compatibility, a traditional @supports rule is often preferable.
Multiple Conditions
An if() function can contain multiple conditions, allowing several possible values to be selected.
For example:
.notice {
--status: info;
border-color: if(
style(--status: success): green;
style(--status: warning): orange;
style(--status: error): red;
else: blue
);
}
The browser checks each condition from top to bottom.
Because --status equals info, none of the three style conditions match, so the border color becomes blue.
If the custom property changes to error, the border becomes red.
Conditions can also use different test types:
.box {
padding: if(
media(width < 600px): 10px;
style(--size: large): 30px;
else: 20px
);
}
When both conditions are true, the first matching branch wins. In this example, a narrow viewport selects 10px even if --size is large.
Place more specific or higher-priority conditions before broader conditions.
Using else
The else keyword provides a value when earlier conditions do not match.
For example:
.box {
width: if(
style(--size: large): 300px;
else: 150px
);
}
The width is 300px when --size equals large. Otherwise, it is 150px.
Without an else branch:
.box {
width: if(style(--size: large): 300px);
}
If the condition is false, the function produces a guaranteed-invalid result. The declaration does not simply fall back to an earlier width declaration.
For example:
.box {
width: 150px;
width: if(style(--size: large): 300px);
}
In a browser that supports if(), the second declaration can override the first even when the condition does not match, causing the property to resolve through invalid-at-computed-value-time behavior.
For predictable results, provide an else value:
.box {
width: 150px;
width: if(style(--size: large): 300px; else: 150px);
}
The else branch is normally placed last because it always matches if evaluation reaches it.
Logical Operators
Conditions can use logical operators to combine or reverse tests.
| Operator | Description |
|---|---|
and |
Requires both conditions to be true. |
or |
Requires at least one condition to be true. |
not |
Reverses the result of a condition. |
For example, and can test two custom properties:
.panel {
background-color: if(
style((--theme: dark) and (--contrast: high)): black;
else: #333
);
}
The background becomes black only when both custom property conditions match.
The or operator allows either condition to match:
.panel {
background-color: if(
style((--theme: dark) or (--theme: midnight)): #222;
else: #fff
);
}
The not operator reverses a condition:
.panel {
color: if(
not style(--theme: dark): #222;
else: #fff
);
}
Logical operators are useful when a single CSS value depends on multiple related conditions.
Partial Property Values
The if() function can select an entire property value or a component within a larger value.
For example, it can select the border style:
.box {
--border-type: dashed;
border: 3px if(
style(--border-type: dashed): dashed;
else: solid
) #0066cc;
}
The border width and color remain unchanged. Only the border style depends on the condition.
The function can also be used inside calc():
.box {
--layout: wide;
width: calc(
if(style(--layout: wide): 70%; else: 50%) - 20px
);
}
When --layout equals wide, the width is calculated as 70% minus 20px. Otherwise, it is calculated as 50% minus 20px.
Selected values must be valid in the surrounding expression.
Nested Conditions
An if() function can contain another if() function.
For example:
.card {
--theme: dark;
color: if(
style(--theme: dark):
if(
media(prefers-contrast: more): white;
else: #ddd
);
else: #222
);
}
The outer condition checks whether the theme is dark.
If it is, the inner condition checks the user's contrast preference and selects either white or light gray text.
If the theme is not dark, the outer else branch selects dark text.
Nesting is useful for related conditions, but deeply nested expressions can become difficult to read.
For complex layouts or many conditional declarations, separate CSS rules may be easier to maintain.
Browser Fallbacks
Because if() has limited browser availability, provide a conventional CSS declaration before the conditional declaration.
For example:
.box {
padding: 20px;
padding: if(
media(width < 600px): 10px;
else: 20px
);
}
Browsers that do not support if() use the first padding declaration.
Browsers that support if() evaluate the condition and select the appropriate value.
A fallback declaration and an else branch serve different purposes:
| Fallback | Purpose |
|---|---|
| Earlier CSS declaration | Provides a value for browsers that do not recognize if(). |
else branch |
Provides a value when no earlier condition matches in browsers that support if(). |
For responsive layouts that must behave consistently in older browsers, use traditional media queries as the primary implementation.
Example
This example uses a custom property to select different card colors. The second declaration provides conditional colors in browsers that support if().
HTML:
<div class="if-demo">
<div class="if-demo-card if-demo-light">
<strong>Light Theme</strong>
<p>--theme: light</p>
</div>
<div class="if-demo-card if-demo-dark">
<strong>Dark Theme</strong>
<p>--theme: dark</p>
</div>
</div>
CSS:
.if-demo {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
max-width: 440px;
margin: 0 auto;
}
.if-demo-card {
padding: 22px 10px;
border: 1px solid #ccc;
border-radius: 5px;
text-align: center;
background-color: #eaf3ff;
color: #222;
background-color: if(
style(--theme: dark): #263445;
else: #eaf3ff
);
color: if(
style(--theme: dark): #fff;
else: #222
);
}
.if-demo-card p {
margin: 8px 0 0;
font-size: 12px;
color: inherit;
}
.if-demo-light { --theme: light; }
.if-demo-dark { --theme: dark; }
--theme: light
--theme: dark
In a supporting browser, the light card receives a pale blue background and dark text, while the dark card receives a dark background and white text.
In browsers without if() support, both cards use the light fallback colors. This difference is intentional and demonstrates why browser support matters.
Responsive Example
This example changes a box's padding based on the viewport width.
HTML:
<div class="if-responsive-demo">
Resize the browser window to test the conditional padding.
</div>
CSS:
.if-responsive-demo {
max-width: 440px;
margin: 0 auto;
padding: 30px;
border: 2px solid #0066cc;
border-radius: 5px;
background-color: #eaf3ff;
color: #222;
text-align: center;
padding: if(
media(width < 600px): 12px;
else: 30px
);
}
In a browser supporting if(), the box uses 12px padding when the viewport is narrower than 600px and 30px otherwise.
In an unsupported browser, the box retains the 30px fallback padding.
The media condition tests the viewport, not the width of the Browser Result container.
if() vs. @media
The if() function and the @media at-rule both support conditional styling, but they operate at different levels.
| Feature | if() | @media |
|---|---|---|
| Purpose | Selects a value inside a CSS declaration. | Conditionally applies CSS rules. |
| Placement | Inside a property value. | Around CSS rule blocks. |
| Conditions | Style, media, and feature support tests. | Media queries. |
| Multiple properties | Each property needs its own conditional value. | One rule can contain multiple declarations. |
| Browser availability | Limited availability. | Widely available. |
For example, using if():
.box {
padding: if(media(width < 600px): 10px; else: 20px);
}
An equivalent traditional media query approach is:
.box {
padding: 20px;
}
@media (width < 600px) {
.box {
padding: 10px;
}
}
Both approaches can produce the same result in supporting browsers.
Use if() for concise conditional values when browser support permits. Use @media when compatibility or grouped responsive styles are more important.
Common Uses
The if() function can simplify conditional values in CSS.
| Use | Description |
|---|---|
| Component themes | Select colors based on custom property values. |
| Responsive spacing | Adjust padding and margins based on viewport dimensions. |
| Browser features | Select values based on supported CSS features. |
| Color schemes | Respond to light or dark mode preferences. |
| Component variations | Apply different values to shared component styles. |
| Calculated values | Select values within expressions such as calc(). |
| Conditional borders | Choose border colors, widths, or styles. |
For example:
.button {
--variant: primary;
background-color: #0066cc;
background-color: if(
style(--variant: primary): #0066cc;
style(--variant: danger): #c62828;
else: #555
);
}
The selected background color depends on the button's --variant custom property.
Limitations
The if() function has several important rules and limitations.
- It has limited browser availability and is still considered experimental.
- Conditions and values are separated by colons.
- Multiple branches are separated by semicolons, not commas.
- Conditions are evaluated in order, and the first matching branch wins.
- An
elsebranch is recommended to handle unmatched conditions. - An unmatched condition without
elsedoes not automatically restore an earlier declaration. - The selected value must be valid for its CSS property or surrounding expression.
- It selects property values rather than conditionally applying entire rule blocks.
- Fallback declarations are needed for browsers without support.
- Complex nested conditions can be harder to maintain than separate CSS rules.
For example, this is valid:
color: if(style(--theme: dark): white; else: black);
The following is incorrect because branches use commas instead of semicolons:
color: if(style(--theme: dark): white, else: black);
The following is also incorrect because it omits the colon between the condition and its value:
color: if(style(--theme: dark) white; else: black);
Use the correct separators and include appropriate fallback values.
Browser Support
The CSS if() function has Limited availability and is not Baseline because it is not supported in all widely used browser engines.
Support began in Chromium-based browsers, including Chrome 137 and Edge 137. Compatibility with other browsers and individual condition types should be checked before production use.
For example:
.box {
color: #222;
color: if(
style(--theme: dark): white;
else: #222
);
}
The first declaration provides a fallback for browsers that do not support if().
For current compatibility information, visit Can I Use? and search for CSS if().
Because the feature is experimental, test it in the browsers required by your project before relying on it for essential styling.
Specifications
The if() function is defined in the CSS Values and Units Module Level 5 .
The specification defines conditional branches, their evaluation order, the else keyword, and how selected values are substituted into CSS declarations.
Related CSS features include the @media, @supports, and @container at-rules, along with custom properties and the calc() function.
