CSS @function, if(), and Upcoming Mixins
When to Use
When you need reusable CSS logic — custom functions for computed values, conditional values based on context, or shared style blocks — without a preprocessor.
Decision
| If you need... | Use... | Why |
|---|---|---|
| Reusable calculated value | @function (Chrome 141+) |
Native CSS function, no build step |
| Conditional value based on media/container/style | if() (Chrome 137+) |
Inline conditional without custom property workaround |
| Shared block of declarations | @mixin / @apply (experimental) |
Replaces Sass mixins — not yet in stable browsers |
| Cross-browser reusable values today | Custom properties + calc() |
Universally supported pattern |
Pattern
/* @function — Chrome 141+ */
@function --fluid-size(--min, --max, --min-vw: 320px, --max-vw: 1200px) {
--slope: (var(--max) - var(--min)) / (var(--max-vw) - var(--min-vw));
--intercept: var(--min) - var(--slope) * var(--min-vw);
result: clamp(var(--min), var(--intercept) + var(--slope) * 100vw, var(--max));
}
h1 { font-size: --fluid-size(1.5rem, 3rem); }
h2 { font-size: --fluid-size(1.25rem, 2rem); }
/* if() — Chrome 137+ */
.container {
padding: if(
media(width >= 768px): 2rem;
else: 1rem;
);
}
.card {
background: if(
style(--theme: dark): oklch(25% 0 0);
style(--theme: light): oklch(98% 0 0);
else: white;
);
}
/* @mixin / @apply — experimental (Chrome Canary only) */
@mixin --flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.hero { @apply --flex-center; }
.modal { @apply --flex-center; }
if() condition types:
- media(...) — media query condition
- style(...) — style query (custom property check)
- supports(...) — feature query
- else — fallback
Browser support:
- @function: Chrome 141+. No Firefox/Safari yet.
- if(): Chrome 137+. No Firefox/Safari yet.
- @mixin/@apply: Chrome Canary only (behind flag). Very early.
All three are Chromium-first. Use custom properties + calc() for cross-browser until support widens.
Common Mistakes
- Using
@functionto return multiple declarations — functions return a single value viaresult:, not a block of properties (that's what@mixinis for) - Nesting
if()insideif()— not supported; use multiple conditions with semicolons - Assuming these replace Sass today — Chromium-only means you still need Sass/PostCSS for production cross-browser code
See Also
- @property → for typed custom properties used with functions
- Native Nesting → another Sass-replacement feature that IS cross-browser
- Reference: Chrome: CSS Functions
- Reference: Chrome: CSS if()
- Reference: MDN: @function