Nesting media queries
In my presentation at Mobilism 2011
(slides) I talked
about using logical and and or in media queries. Most of us use
and, but I found that not as many people knew about the logical or,
which in the case of media queries is the comma. In comma-separated
media queries, like this one:
@media screen and (min-resolution: 300dpi), screen and (-webkit-min-device-pixel-ratio: 2) { }
the comma is an or. The first query will be evaluated. If not true,
the second one will be evaluated. If one of these is true, the styles
will be applied. Another thing I mentioned (which is on the video but
unfortunately not in the slides) is that it is possible to nest media
queries. Since we can use media queries in the link element as well
as in a CSS file itself, I found that doing both allows you some simple
nesting. Whenever you want to apply styles based on two conditions
which cannot be fulfilled within a single query, this could be useful. I
couldn't think of any other use cases at the time other than my typical
use case of using min-width queries and having specific page
components which need to change at a certain max-width. That works
just fine. But then just yesterday
Ben Callahan provided us all a new
use case: working with logical not. As I discussed at Mobilism, it is
possible to create a media query like so:
@media not screen and (min-width: 600px) { }
This might look like it means “if it's not a screen but it is at least
600px wide, then apply these styles.” In fact, the not negates the
entire query. This is according to spec. So this query actually says,
“if it's not a screen which is at least 600px wide, apply these styles.”
That's a huge difference. Ben sent
an
article which he and Matt
Griffin wrote in which they describe this problem, as in one key
example they wanted to target all media types which are not print. You
can't do:
@media not print and (min-width: 60em)
and expect the min-width to still apply, since the not negates the
entire query. So, glad with another possible use case for nesting media
queries, I suggested the idea to Ben, who promptly added some nesting
tests to the slew of
media query tests he'd done for the article. As far as I can tell,
Ben's tests work as expected. By linking to a style sheet like so:
and then in that style sheet creating another query like so:
@media all and (min-width: 60em)
you have created a nice little nested conditional, saying, “as long as the media type is not print, if the minimum width is 60em, apply these styles”. Of course, the only styles that will be applied are those in that particular query block in your style sheet. While I could confirm Ben's tests worked in a couple of modern browsers (and an actual printer, of course), it obviously will not work in any browser which doesn't support the not keyword. And as always, I'm sure there are several other caveats to be found. Nevertheless, it's a useful trick to know. Hats off to Ben and Matt for their explorations. Great stuff! NOTE (2012-10-17): As Bruce Lawson pointed out to me, browsers will most likely support nesting of media blocks in the future.
Comments
Ben Callahan
Nice write-up, thanks for the idea to give this a try! I’ll clean up the example and start thinking through some more use cases.
Matt Smith
Great write up. Really useful to understand.
Ady COles
Excellent piece. A good solution. Looking forward to better browser support, though!
Tony Porto
Does anyone know if it is possible to nest media queries inside media queries??
Example:
= @media all and (min-width: 721px) { =
#somecss {width:90%}
@media all and (max-width: 920px) { #css {margin-left:1%}
}/*closes 721px to 920*/ }/*closes 721px to all*/
It would make sense however I do not see anyone using this technique? Anyone?
lolmaus
Hey Tony Porto, it’s possible to nest min/max witdth queries inside media type queries or resolution queries, but not inside other min/max width queries.
Jason
THANK YOU! This finally let me use the “not” operator the way I wanted to.