If you're like me, you've probably been stretching CSS variables / custom properties to their limits while building your own design systems. But this "silver bullet" can lead to a nasty roadblock: you can't use them in media query declarations.
Tip: Media Queries are about defining different style rules for different devices (screens, tablets, mobile phones, etc.). You can learn more Media Queries in our Media Queries Chapter. Here, we first declare a new local variable named --fontsize for the . container class.
CSS declared inline This may be the reason why your media queries aren't working. That is to say, you may have declared CSS within your HTML document. So if this is the case, simply go through the HTML document and remove the CSS declared inline.
The @media rule is used in media queries to apply different styles for different media types/devices. Media queries can be used to check many things, such as: width and height of the viewport. width and height of the device. orientation (is the tablet/phone in landscape or portrait mode?)
From the spec,
The
var()
function can be used in place of any part of a value in any property on an element. Thevar()
function can not be used as property names, selectors, or anything else besides property values. (Doing so usually produces invalid syntax, or else a value whose meaning has no connection to the variable.)
So no, you can't use it in a media query.
And that makes sense. Because you can set --mobile-breakpoint
e.g. to :root
, that is, the <html>
element, and from there be inherited to other elements. But a media query is not an element, it does not inherit from <html>
, so it can't work.
This is not what CSS variables are trying to accomplish. You can use a CSS preprocessor instead.
As Oriol has answered, CSS Variables Level 1’s var()
cannot currently be used in media queries. However, there have been recent developments that will address this problem. Once CSS Environment Variables Module Level 1 is standardized and implemented, we’ll be able to use env()
variables in media queries in all modern browsers.
The Chromium team at Google has already started working on env()
. In response, the CSS Working Group (CSSWG) codified env()
in a new standard (currently at the draft stage): the CSS Environment Variables Module Level 1 (see this GitHub comment and this comment for more info). The draft calls out variables in media queries as an explicit use case:
Because environment variables don’t depend on the value of anything drawn from a particular element, they can be used in places where there is no obvious element to draw from, such as in
@media
rules, where thevar()
function would not be valid.
If you read the specification and have a concern, or if you want to voice your support for the media-query use case, you can do so in this GitHub issue or in any CSS GitHub issue prefixed with “[css-env-1]”.
GitHub issue #2627 and GitHub issue #3578 are devoted to custom environmental variables in media queries.
Original answer from 2017-11-09:
Recently, the CSS Working Group decided that CSS Variables Level 2 will support user-defined environment variables using env()
, and they will try to make them be valid in media queries. The Group resolved this after Apple first proposed standard user-agent properties, shortly before the official announcement of iPhone X in September 2017 (see also WebKit: “Designing Websites for iPhone X” by Timothy Horton). Other browser representatives then agreed they would be generally useful across many devices, such as television displays and ink printing with bleed edges. (env()
used to be called constant()
, but that has now been deprecated. You might still see articles that refer to the old name, such as this article by Peter-Paul Koch.) After some weeks passed, Cameron McCormack of Mozilla realized that these environment variables would be usable in media queries, and Tab Atkins, Jr. of Google then realized that user-defined environment variables would be especially useful as global, non-overridable root variables usable in media queries. Now, Dean “Dino” Jackson of Apple will join Atkins in editing Level 2.
You can subscribe to updates on this matter in w3c/csswg-drafts
GitHub issue #1693 (for especially relevant historical details, expand the meeting logs embedded in the CSSWG Meeting Bot’s resolutions and search for “MQ”, which stands for “media queries”).
What you can do however is @media query your :root
statement!
:root {
/* desktop vars */
}
@media screen and (max-width: 479px) {
:root {
/* mobile vars */
}
}
Totally works in Chrome, Firefox and Edge at least the latest production versions as of this posting.
One limitation: if you need to access the value as a variable – for example to use in calculations elsewhere – you will need to have a variable, and it requires defining the variable in two places: the media query and variable declaration.
Apparently it's just not possible to use native CSS variables like that. It's one of the limitations.
A clever way to use it is to change your variables in the media-query, to impact all your style. I recommend this article.
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
One way to achieve what you want is using npm package postcss-media-variables
.
If you are fine with using npm packages then you can take a look documentation for same here:
Example
/* input */
:root {
--min-width: 1000px;
--smallscreen: 480px;
}
@media (min-width: var(--min-width)) {}
@media (max-width: calc(var(--min-width) - 1px)) {}
@custom-media --small-device (max-width: var(--smallscreen));
@media (--small-device) {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With