TIL that calc() works inside @media query conditions for static calculations, but CSS custom properties (var()) cannot be used in media query conditions.
What Works: Static calc()
You can use calc() directly in media queries with hardcoded values:
/* This works! */
@media (min-width: calc(100px * 2 + 2rem)) {
.container {
display: grid;
}
}
Browser Support: Widely supported
What Doesn’t Work: CSS Custom Properties
According to the CSS Variables Level 1 spec, var() cannot be used in media query conditions:
/* ❌ This does NOT work */
:root {
--breakpoint: 768px;
}
@media (min-width: var(--breakpoint)) {
/* This will fail */
}
/* ❌ This also does NOT work */
@media (min-width: calc(var(--breakpoint) + 100px)) {
/* This will fail too */
}
Why? Media queries exist in global scope and aren’t attached to HTML elements, so they can’t access CSS custom properties—even from :root. When SASS/SCSS nests @media blocks, they’re hoisted to the document base during compilation, further illustrating this separation.
Workarounds
For SASS/SCSS Users
Use SASS variables for media queries (replaced at build-time) and CSS variables everywhere else:
$mobile-breakpoint: 600px;
@media (max-width: calc($mobile-breakpoint + 2rem)) {
/* ✅ Works */
}
For PostCSS Users
The @csstools/postcss-design-tokens plugin lets you use design tokens from JSON files, including in media queries:
// tokens.json
{
"viewport": {
"mobile": { "value": "600px" },
"tablet": { "value": "900px" }
},
"spacing": {
"small": { "value": "16px" }
}
}
@design-tokens url('./tokens.json') format('style-dictionary3');
.container {
padding: design-token('spacing.small');
}
/* ✅ This works in media queries! */
@media (min-width: design-token('viewport.mobile')) {
.container {
padding: design-token('spacing.small' to rem);
}
}
This compiles to standard CSS with your token values replaced.
Note on deprecated postcss-env-function: Custom Environment Variables were never formally specified and are no longer included in postcss-preset-env. If you’re still using it, consider migrating to @csstools/postcss-design-tokens.
Future: Native env() Variables
The CSS Environment Variables Module Level 1 spec proposes native env() support for media queries. While browsers support env() for reading predefined values (like safe area insets), you cannot declare custom environment variables yet.