Nesting media queries

October 17, 2012October 17, 2012

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:

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.