34

By default I want to give my body element a green border. On a device that supports retina display I want to check for size first. On an ipad I want to give my body a red border and on an iphone I want to give it a blue border. But nesting media queries like so doesn't work:

body { border: 1px solid green; }

@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { 
   @media (max-width: 768px) and (min-width: 320px) {
      body { border: 1px solid red; }
   }
   @media (max-width: 320px) {
      body { border: 1px solid blue; }
   }
}
1
  • Not sure what the question is here, but if you want to know whether your CSS is validation you can check it with the W3C CSS Validation Tool. I have tried it with nested media queries and it didn't like it... You can access the tool here: jigsaw.w3.org/css-validator Commented Aug 13, 2015 at 18:10

2 Answers 2

31

No. You need to use the and operator and write that as two queries. You can, however, do this in SCSS, which will compile to CSS, but it will combine them by unfolding them and using the and operator.

This is a common problem, and once I first wrote LESS or SCSS, I didn't ever want to go back to writing this long-hand.

Long-handed CSS:

@media (-webkit-min-device-pixel-ratio: 2) and (max-width: 768px) and (min-width: 320px),
                  (min-resolution: 192dpi) and (max-width: 768px) and (min-width: 320px) {
  body {
    border: 1px solid red;
  }
}
@media (-webkit-min-device-pixel-ratio: 2) and (max-width: 320px),
                  (min-resolution: 192dpi) and (max-width: 320px) {
  body {
    border: 1px solid blue;
  }
}

Nesting queries may work, but support varies across browsers.

4
  • 1
    can you please provide an example doing it the long hand way. I can't use any CSS precompilers at the company I work, at least not for this current project.
    – user967451
    Commented Apr 19, 2013 at 21:59
  • 1
    You can nest them, but flattening them is the only way to ensure cross-browser validity.
    – nickhar
    Commented Apr 19, 2013 at 23:29
  • In fact looking at the original logic, that probably needs to be unwound into four rules not two in order to be the same. SCSS is so much easier.
    – cirrus
    Commented Apr 20, 2013 at 8:42
  • 1
    I've corrected the query to ensure it's the same as your orginal (in fact I just ran it through LESS for ease. I'd be surprised if you couldn't make the case for LESS on your project citing exactly this example. I don't tend to use browser compilation, OR server compilation, I just build the CSS files as I go along. There are a number of command line methods for this or there are editor plugins that allow you to write LESS and spit out CSS. I find it hard to imagine any project would prevent you from doing that. There are even online tools. eg. lesstester.com
    – cirrus
    Commented Apr 20, 2013 at 8:53
15

In 2020, yes!

Actually the accepted answer has been outdated for a long time now. I'm not even sure if it was technically correct even at the time of posting. Firefox has supported nesting since 2012 and Chrome since 2013 (source).

You should expect support from all major browsers now, of course with the usual exception of IE.

You can test it using the following HTML and CSS. Just open up dev panel in your browser and vary your viewport width.

#abc {
  background: green;
}
/* width < 801px */
@media (max-width: 800px) {
  #abc#abc {
    background: red;
  }
  /* 500px < width < 801px */
  @media (min-width: 500px) {
    #abc#abc#abc {
      background: yellow;
    }
  }
}
<div id="abc">Example text</div>

Alternatively, check out this codepen.