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:
- 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-widthbe with you, unless you have a budget and/or schedule that allows you to refactor during development. - You're making an existing website responsive, and the existing CSS is design baggage you've inherited and cannot change, for whatever reason.
- 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.
Comments
Jan van Hellemond
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
Adam W.
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.
Peter Guntrip
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.
Stephen
@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?
Francis Kim
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.
Scott Richardson
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.