Grow your CSS skills. Land your dream job.

Logic in Media Queries

Published by Chris Coyier

Just in case you have brain farts about this constantly like I do.

If

That's what media queries are: logical if statements. "If" these things are true about the browser, use the CSS inside.

And

The keyword and.

@media (min-width: 600px) and (max-width: 800px) {
  html { background: red; }
}

Or

Comma separate.

@media (max-width: 600px), (min-width: 800px) {
  html { background: red; }
}

Technically these are treated like two separate media queries, but that is effectively or.

Not

Reverse the logic with the keyword not.

@media not all and (max-width: 600px) {
  html { background: red; }
}

Just doing not (max-width: 600px) doesn't seem to work for me, hence the slightly funky syntax above. Perhaps someone can explain that to me. Note that not only works for the current media query, so if you comma separate, it only affects the media query it is within. Also note that not reverses the logic for the entire media query as a whole, not individual parts of it. not x and y = not (x and y) ≠ (not x) and y

Exclusive

To ensure that only one media query is in effect at time, make the numbers (or whatever) such that that is possible. It may be easier to mentally manage them this way.

@media (max-width: 400px) {
  html { background: red; }
}
@media (min-width: 401px) and (max-width: 800px) {
  html { background: green; }
}
@media (min-width: 801px) {
  html { background: blue; }
}

Logically this is a bit like a switch statement, only without a simple way to do "if none of these match do this" like default.

Overriding

There is nothing preventing more than one media query from being true at the same time. It may be more efficient to use this in some cases rather than making them all exclusive.

@media (min-width: 400px) {
  html { background: red; }
}
@media (min-width: 600px) {
  html { background: green; }
}
@media (min-width: 800px) {
  html { background: blue; }
}

Media queries add no specificity to the selectors they contain, but source order still matters. The above will work because they are ordered correctly. Swap that order and at browser window widths above 800px the background would be red, perhaps unintuitively.

Mobile First

Your small screen styles are in your regular screen CSS and then as the screen gets larger you override what you need to. So, min-width media queries in general.

html { background: red; }

@media (min-width: 600px) {
  html { background: green; }
}

Desktop First

Your large screen styles are in your regular screen CSS and then as the screen gets smaller you override what you need to. So, max-width media queries in general.

html { background: red; }

@media (max-width: 600px) {
  html { background: green; }
}

Gettin Wacky

You can be as complex as you want with this.

@media 
  only screen and (min-width: 100px),
  not all and (min-width: 100px),
  not print and (min-height: 100px),
  (color),
  (min-height: 100px) and (max-height: 1000px),
  handheld and (orientation: landscape)
{
  html { background: red; }
}

Note the only keyword was intended to prevent non-media-query supporting browsers to not load the stylesheet or use the styles. Not sure how useful that ever was / still is.

Comments

  1. This is ace, I too have the occasional brain fart about this! Thanks :D

  2. As always a great walk-through. A brainfart post that warmed me up to media queries.

  3. What’s the use case for not? Is there something you can do with @media not all and (max-width: 600px) that you couldn’t do with @media (min-width: 801px)?

    I guess maybe you need it when building up complicated queries clause by clauses, like in the last example in the article. But do you really?

    • Logic is a strange beast. Sometimes being specific in language about what you aren’t doing makes more sense.

      I also think there might be some boolean keywords that require not to be the opposite like maybe not (color) – but not quite sure. I know there is monochrome but I’m not sure if that’s the exact opposite of color not.


      Gypsy: “There is perhaps one way. Have you heard of the monks of Deshuba?”

      Fry: “I’ve… NOT heard of them…”

      http://www.gotfuturama.com/Multimedia/EpisodeSounds/3ACV20/24.mp3

  4. Great round-up! I have used specific heights as a way to test retina graphics before.

    @media 
    (height: 899px),
    (-webkit-min-device-pixel-ratio: 2),
    (min-resolution: 192dpi) {
         .wrapper {background:url(img/image@2x.jpg);}
    }

    The first @media argument is just height (not min or max), which makes the testing a lot easier.

  5. Many of my responsive design problems would be solved by being able to change a layout depending on the width/height of an element’s container rather than the viewport. I hope this happens one day.

  6. I have been using the mobile first approach, but I hate the fact that I basically have to recreate my stylesheet for IE8 since it ignores the media queries. Anyone have any tips for improving that workflow?

    • Stephen

      Actually yes, do it in the reverse. In your main workflow assume you are designing for a non media query site (eg: desktop, IE8) then only use Media Queries where you need to, and keep them at the bottom of your style sheet. It’s not exactly mobile first design, but I have found it very easy to use by only amending exactly what needs to change for specific device, width etc… At the very least it stops you duplicating all of your code in each media query, by assuming the worst scenario (IE7,IE8) and then applying progressive improvements, tweaks to suit.

      /* site defaults */
      html {background: red; padding:0; margin:0; etc.....}
      
      /*mobile*/
      @media (max-width: 400px) { 
        html { background: blue; }
      }
      
      /* tablet */
      @media (min-width: 401px) and (max-width: 800px) {
        html { background: green; } 
      }
      
      /* This doesn't have to exist unless your design needs it, as these settings are above */
      @media (min-width: 801px) and (max-width: 1199px) {
        html { background: red; }
      }
      
      /* large desktop and browsers that know a media query*/
      @media (min-width: 1200px) {
        html { background: blue; }
      }
    • dtgreen

      @Stephen Surely the Mobile First approach is more about the order in which you create the media queries (smaller viewports –> larger viewports) than where the actual queries are found in the document?

      Whenever I’m doing responsive work I always put everything in one lock at the bottom of the stylesheet, rather than having each one adjacent to the relevant selector etc.

    • I use conditional comments on the HTML element and then use LESS to contain all my media queries and then also feed them to IE7 and IE8.

      This way I only have to write the media queries once and IE still gets a decent desktop experience.

      @media only screen and (min-width: 480px)    { .480; }
      @media only screen and (min-width: 600px)   { .600; }
      @media only screen and (min-width: 760px)   { .760; }
      @media only screen and (min-width: 980px)   { .980; }
      @media only screen and (min-width: 1380px)    { .1380; }
      .ie7, .ie8                                 { .480; .600; .760; .980; }

      I guess it would probably also be more efficient to have a separate stylesheet which then just gets conditionally included for IE to save stop the duplication in the main CSS file but this is the theory.

  7. Andre

    Please check out CSS Media Query Live Demo and Cheat Sheet.

    Hope it’s helpful for the developers and designers.

    https://github.com/AndreLion/mediaquery

  8. Nice article! I really would like to get a tutorial about common CSS media queries that support the majority of mobile devices out there, meaning small/large smartphones, tablets, different viewport orientations etc… I don’t want to support each device viewport, but the the most common… Any suggestions?

  9. Great article chris, simple and straightforward!

  10. Nicole

    Really appreciate this, especially going over ‘not’.

  11. Thanks for this concise clarity in the media query mayhem. Exclusive and Overriding examples hit the spot!

  12. Cesidio

    Once again, you prove why devs flock to you when it comes to CSS. You simplify things very nicely.

  13. Efraim

    I would love some info in how printers respond to media queries. What’s a printers “min-width”?!

  14. Vipul

    Hi there,
    I am using media query for a responsive web. I used top down approach from desktop to smaller devices, but when it comes to test in android devices that is really pain. For example an android device with resolution 800×480 get conflict with iPad resolution 768×1024.

    I have tried “min-device-width” to “max-device width” for both but then also result same.

    What can be the solution for this kind of situation? Help….

    • The solution is, generally speaking, mobile-first styling. By doing things mobile-first, your focus is more around the content, and adding styles as capability (and size) allows, instead of trying to strip away things when the viewport becomes too small.

      Proportional media queries can also help, because they no longer care about pixel dimensions (which helps for edge cases such as the Kindle Fire or a projector).

    • Sach
      Permalink to comment#

      Hey Vipul,

      Can you guide me in how you went about changing the stylesheet to incorporate the media query changes for responsive web design.

      Any help will be appreciated

    • seelan
      Permalink to comment#

      Hello Sach,

      Try like this,

        @media screen and (max-width: 800px)
        @media screen and (max-width: 768px)
      
  15. Thanks for explaining it so I can finally understand

  16. gcyrillus

    here is 2 links that could be very useful:

    http://www.mobitest.me/ tells about the screen and features supported .

    http://www.mobitest.me/devices/ a listing of common mobile values

  17. I suppose it all depends on the contraints of the project as to which of the approaches you covered as to which is the most sufficient and code efficient approach.

  18. Manuel Lama
    Permalink to comment#

    @media not, (max-width: 600px) {
    html { background: red; }
    }

    Adding the comma seems to work for me in the not media query.

  19. seelan
    Permalink to comment#

    @media (min-width: 801px) and (max-width: 1365px){
    /* style goes here */
    }
    I m using this media query. this is not working up to max-width:1365px. it works till 1224px only.
    help me!!!

    • Are you sure you aren’t overriding it with some other query?

      A side note to everybody, be careful if you use some online CSS minifiers, because some of them destroy the @media code :)

    • seelan
      Permalink to comment#

      ya i am sure it is not overriding with some other media queries.

  20. msz900
    Permalink to comment#

    how to use max or min-height with media queries any example and what’s the d/f b/w @media(max-width:etc)
    and @media screen and(max-width:etc)
    and @media all ?

  21. Karan
    Permalink to comment#

    I am using media query for a responsive web, commonly we are using media queries like this:

    @media (min-width: 1024px) and (max-width: 1280px){
    /* style goes here */
    }

    It’s fine….

    My Question is this, If we have to control the height through media query then what to do.
    As you guys know some users using 1280-768 resolutions and some are using 1280-960/1024 some are using hire resolutions. We developers are stuck on this occasions. I need help and want the solution from you guys….

  22. Hi there. I’m ‘stacking’ some media queries for retina and also mon-width as so:

    .stuff {
        width: 15px;
        height: 15px;
        background-size: 15px;
    }
    
    @media only screen and (min-width: 47em) {
        .stuff {
            background-size: 25px;
            width: 25px;
            height: 25px;
        }
    }
    
    @media only screen and (min-width: 47em) and (-webkit-min-device-pixel-ratio: 2),
    only screen and (   min--moz-device-pixel-ratio: 2),
    only screen and (     -o-min-device-pixel-ratio: 2/1),
    only screen and (        min-device-pixel-ratio: 2),
    only screen and (                min-resolution: 192dpi),
    only screen and (                min-resolution: 2dppx) {
        .stuff {
            background-size: 50px;
            width: 50px;
            height: 50px;
        }
    }
    
    @media only screen and (min-width: 54em) and (-webkit-min-device-pixel-ratio: 2),
    only screen and (   min--moz-device-pixel-ratio: 2),
    only screen and (     -o-min-device-pixel-ratio: 2/1),
    only screen and (        min-device-pixel-ratio: 2),
    only screen and (                min-resolution: 192dpi),
    only screen and (                min-resolution: 2dppx) {
        .stuff {
            background-size: 30px;
            width: 30px;
            height: 30px;
        }
    }
    

    My problem is that the last Media Query is overriding everything. I can’t seem to figure out why. I would have thought that it’s predecessor would override it if the width matched.

    Any one know why?

    Cheers

  23. sergio zambrano

    I haven’t tried it, but you can’t start something with not. Afaik, the “not” logic is to subsctract elements from an initial group. So you should start with the rest, and then add the not substraction. Your hacks are probably working because you are forcing for a whole group to be defined (other than where the not is) to have something to substract from.

  24. mail@johannheyne.de
    Permalink to comment#

    I just would like to have…

    @media screen and ( .selector min-width: 400px ) {
    
    }
    
    @media screen and ( .selector wordwrap ) { 
        /* useful for horizontal menus */
    }
    

    :-)

  25. Karlos
    Permalink to comment#

    @media screen and (max-width:800p×) and (max-height:480px) {
    }
    @media screen and (max-width:1024p×) and (max-height:768px) {
    }
    @media screen and (max-height:800p×) and (max-width:480px) {
    }
    @media screen and (max-height:1024p×) and (max-width:768px) {
    }

    I don’t see how these override each other, can someone explain please?

    Best,
    Karl

  26. chethanram
    Permalink to comment#

    All above 3 styles are in my website How can I make only 2 of them for desktop can load
    same way in mobile i need call one style

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".