Choosing between min-width and max-width media queries

I’m often asked a variation of the following question:

Should I use min-width or max-width media queries?

The obvious answer is, of course, “yes”. But you know what they’re asking: which of the two is better?

Those for whom responsive design has become second nature might find it an odd question, and will know that the answer is, “it depends”. But having seen lots of responsive design implementations, it’s clear to me that many designers and developers aren’t quite sure. And I’m happy to share my own opinion of what “it depends” means regarding this particular question.

Desktop first and max-width

There’s a decent number of designers/developers that still think of “the desktop” as their primary design manifestation, with other (generally smaller) sizes as secondary; often these appear as afterthoughts, since there can be significant visual clues as to the amount of effort that has gone into these other screen sizes when compared to their desktop counterparts. Often, when one examines the CSS of these sites, `max-width` is the media feature of choice.

This makes sense. If a design is built desktop-first, then all the CSS for the desktop-ish version of the design has been written, and must be overridden with more CSS for any other breakpoints. If a given desktop-ish width is our baseline and we are unwilling or unable to refactor our CSS, then it seems logical to override what is now our base CSS for all viewport widths with those we only want to apply to smaller widths.

This can lead to a situation I’ve often joked about: writing styles only to undo them later. This is an example I often use (assume .related takes the form of a sidebar):


.content {
  width: 60%;
}

.related {
  width: 40%;
}

@media screen and (max-width: 37.4em) {
  .content,
  .related {
    width: 100%;
  }
}

The above example omits a lot, but I’m sure you get the idea. This approach, when used over a bunch of components, can greatly increase the amount of CSS needed to complete the project. But the main problem is how illogical it is, because when embracing the fact the block-level elements are 100% of their parent by default, then the following makes much more sense:


@media screen and (min-width: 37.5em) {
  .content {
    width: 60%;
  }

  .related {
    width: 40%;
  }
}

Here, we’re making use of the default state of block-level elements, and overriding them when they need to change from the default. Again, it might seem clear to some readers, but it doesn’t take looking at the source of many websites before you understand why I’m clarifying it here.

Using max-width against your better judgement

There are a couple of reasons why, even when you know better, you might deliberately choose to use an approach similar to max-width approach above:

  1. You’re a developer and you received desktop-only, desktop-first, or other-sizes-as-an-afterthought comps from the designer. How can you know? If you’ve only designed or received designs for desktop-ish widths, this is what you’re dealing with. If you’ve got nice detailed desktop-ish designs with a few “mobile” or “tablet” examples thrown in there, this is what you’re dealing with. In these cases, may the max-width be with you, unless you have a budget and/or schedule that allows you to refactor during development.
  2. You’re making an existing website responsive, and the existing CSS is design baggage you’ve inherited and cannot change, for whatever reason.
  3. You’re compensating for the fact that we don’t currently have element queries, and you’re handling this with CSS instead of using a JavaScript polyfill for a non-existent spec.

So, what’s the best to use?

Here’s my clarification of “it depends” for this particular question. And remember it’s just my own opinion based on my own experiences: look at default display of a given element. If you have to override this default for smaller screens, use max-width. If the default is usable on small screens, use min-width, and only when the element needs to deviate from the default. And of course, I recommend letting the content determine where that happens.

A good example of using max-width to override an element’s default display so that it works better on smaller screens is when using tables. Imagine a table that contains too much content to display in its default form on small screens. One approach might be:


@media only screen and (max-width: 30em) {
  .big-table tr,
  .big-table td {
    display: block;
  }
}

This turns each row (and cell) into a block on narrow screens. The table can become quite long vertically and more styling is usually required, but it’s often better than the back-and-forth horizontal scrolling that would otherwise be required to read the content.

In this case, it makes all the sense in the world to leave the table in default form, except for in browsers that understand the media query and where the screen is no larger than, in this case, 30em.

Other elements (I would venture to say most other elements) that have defaults that work fine on smaller screens, only need changing when necessary on larger screens; using min-width is then a solid choice.

In short: let element defaults help determine which media feature to use in your media queries.

Thanks to Brad Frost for reviewing this. He also has a post with related topics.

6 thoughts on “Choosing between min-width and max-width media queries

  1. In defense of the “desktop first” mentality,or to at least explain it a bit; there used to be a time when desktop browsers did not all support media queries and mobile browsers did (to some degree). It made sense then to build for desktop first and apply media queries for smaller screens on top of that, overwriting things indeed. For some of us, that mentality stuck. #guilty

  2. I was going to say what Jan said … IE didn’t support it, so in order to deal with that, you designed for desktop first and then down from there. That’s less and less of an issue, and in most cases, you probably don’t need to worry about that anymore. So, ideally, mobile first is better and always has been.

  3. Be careful about changing td/th cells away from their default CSS display behaviour of ‘table-cell’ – screen readers especially voiceover won’t read out each cell’s associated header title anymore, as it no longer regards it as a table.

  4. @Peter: Thanks for mentioning accessibility, though my example was about the media query and not the table specifically. But to your point: generally, for tables that are not complex, I would use generated content to place the header text in front of the td content in each row. This can be done by adding e.g. a data-header attribute to each td and showing this on small screens using a ::before pseudo-element and hiding the thead. In such cases, I don’t think it would even be desirable for assistive technology to treat this as a table. In my tests, the generated content is read by both Talkback and VoiceOver and the rows assume a role of paragraph or similar. Is this not your experience?

  5. I actually use both (min & max widths – yes it’s probably very bad), only because the work passed to me was set that way – but if I were to set it out from the start, I’d be building desktop-first, only because my brain is wired that way.

  6. I tend to make my Css more organically. Doesn’t matter if it is mobile or desktop first. I’ll begin moving anything unique about the current screen size into a min-max query. As I progress I end up with a bunch of these min-max queries as certain styles only apply within certain widths. As I notice some styles carrying across multiple min-Max queries I create larger min-max queries to hold those. Sometimes I end up with some min-only or max-only queries if styling needs to carry across everything up to or below a certain point. I never have to override anything as everything that changes is within a query. Only things that never change are placed outside a query. Such as a font colour for example. So even my ‘default’ desktop styling is mostly within a min-width query.

Comments are closed.