Media Queries

Demo starter files

Now that we've talked about fluid layouts and the need to be able to display the same content in a variety of ways, it's time to cover media queries, which do exactly that. We're going to adapt our fluid layout demo, adding some media queries to reformat it for different sizes.

Using media queries, we can conditionally apply different CSS rules, or even entirely separate style sheets, based on certain conditions.

A media query basically says "Apply these styles if..."

But before we get too far into the details, here's an example of some very simple media queries in action!

You can use media queries in CSS for portions of your style sheet, or you can use them in HTML, to load an entirely separate style sheet. In CSS, a media query looks like this:

@media screen and (min-width: 500px) {
    /* media-specific rules, usually indented one level */
}

In HTML, it looks like this:

<link rel="stylesheet" media="screen and (min-width: 500px)" href="styles/style-big.css">

You should be familiar with this second method for loading separate style sheets, but most queries are written in the CSS, like the first method.

Viewport Setup

First thing's first. Mobile browsers use zooming to squeeze web sites with fixed or large layouts onto their screens. Unfortunately this also affects media queries' mobile styles. In order to prep a site for mobile styling, we need to add a custom meta tag to the <head> of every HTML document that uses media queries:

<meta name="viewport" content="width=device-width">

It's a good idea to create a "boilerplate" or template for new HTML documents, so you don't forget things like the meta charset and <!DOCTYPE html>. If you do this, just add this meta viewport tag to the list.

A media query can have up to 3 parts: media types, media features, and logical operators.

Media Types

Media types are used for applying styles to a specific genre of device. There are only three media types you should know about:

Name
Summary
screen
Intended for computer screens of any kind
print
Intended for printing and paged media
all
Suitable for all media types

Several other types exist including handheld, projection, and tv, but they are not supported by all browsers, and they are slated to be removed from the spec.

Why? Well, the market for internet connected devices is moving very fast. Phones are getting bigger, tablets are getting faster, TV's not only have keyboards for input, but voice and motion capture as well. All of these new devices are quickly blurring the lines between different categories.

At the same time, web standards move slowly. It generally takes a few years to reach a consensus on how a standard should be implemented, and all the different browser engines have to add support for new standards following W3C guidelines. During the time that it's taken to develop and implement media queries, it's become obvious that putting devices into categories is a pointless exercise.

The print and screen types are distinct categories, and there's a good chance they'll stick around. Beyond that though, we simply write queries to test what features a device supports.

Media Features

Each media feature must be wrapped in parentheses. There are many media features, but here are some of the most common:

Name
Summary
width
Viewport (browser window) width, commonly measured in px, em, or rem. For simple queries this all we need.
height
Viewport (browser window) height
aspect-ratio
Viewport aspect ratio, always expressed as a fraction: 16/9
orientation
Orientation of the device, either portrait or landscape
device-width
Total width of the device. On a desktop, this would be the monitor's total width, not just the size of the browser window. Always prefer using width if possible.
device-height
Total height of the device
device-aspect-ratio
Overall aspect ratio of the device
resolution
Resolution of the device in dpi. Caveats and more info on caniuse

Important: almost all of these features can also have a min- and max- prefix! (min-resolution: 192dpi), (max-width: 800px), and so on.

Logical Operators

We can build more complex media queries by combining media types and features.

and

Links two or more features together, so that all of them must be true for the query to match.

screen and (orientation: landscape) and (min-width: 800px)

or

The word "or" never appears in media queries, but commas often do, and serve the same purpose.

(min-width: 800px), (orientation: landscape)

The above linked style sheet would load if either condition before or after the comma is true.

not

Negates the entire query. Must be used with a media type, not just a feature. All of the query's conditions must be false for the style sheet to load. This must appear at the beginning of the query or the entire query will be ignored! In other words, you can't use it to negate part of a query.

Good:

not screen and (orientation: landscape) and (min-width: 800px)

Query is true if the device is not landscape, and not wider than 800px.

Bad:

screen and (orientation: landscape) and not (min-width: 800px)

This query is ignored. This does not mean "yes landscape, but not wider than 800px". A proper and less confusing way to express this would be without "not", because we're essentially creating a double-negative.

screen and (orientation: landscape) and (max-width: 800px)

Let's break here and do the demo, so you can see these queries in action before we talk about best practices.

Overlapping vs. Stacking

Overlapping queries:

small screens
base styles, no query
medium screens
(min-width: 500px)
large screens
(min-width: 960px)
  • Pro: Styles cascade beautifully creating a nice clear structure of inheritance.
  • Con: Additional lines are needed to cancel out inherited settings (ex. float on, float off).
  • Con: Changing a base style affects all queries, often meaning all queries need to be updated.

Stacking queries:

all screens
base styles, no query
small screens
(max-width: 499px)
medium screens
(min-width: 500px) and (max-width: 959px)
large screens
(min-width: 960px)
  • Pro: Modular approach to targeting different screen sizes.
  • Con: Designing for each query as a separate layout can be just as complicated.
  • Con: See that little gap between queries? Sometimes that's not a gap but an overlap, and either way it's a big potential problem. Are sub-pixels rounded off? What happens if you're smart and use em or rem-based breakpoints? At what decimal does rounding occur?

Our demo uses overlapping queries, but there are compelling arguments for both approaches as style sheets become larger and more advanced.

Note that regardless of which approach you use, media queries must be listed one after another in the style sheet. They cannot be nested in normal CSS the way HTML tags are.

Target For Design, Not Screen Size

Building a web site using media queries to target specific devices or screen sizes is futile - there are far too many devices coming out way too fast to fit them into nice neat categories.

Instead of trying to fit your design to "small, medium, or big" display sizes, you'll need to use a process of testing and playing (especially on a desktop where you can resize the window) to see where logical breakpoints exist in your design.

Unless you're designing primarily for a desktop experience, it's recommended to aim your base styles to be mobile first, and work up from there.

Muddy Waters

This demo is meant to be an introduction to building basic media queries. In reality, media queries become a large, complex, and integral part of designing a production web site.

Testing

When working on responsive designs, developers spend a lot of time testing on real devices.

array of actual handheld devices for testing rwd
The device testing lab used during the development of the BBC News mobile site.
testing responsive web sites on real devices
Developer tools and simulators go a long way, but there's often no substitute for testing on real devices. (Image via smashing magazine)

Without access to a large collection of random devices like this, we still have a few options:

  • Resizing the browser window (obviously).
  • Browser developer tools. Chrome, Firefox, and Safari have excellent features build right into their developer tools for testing device queries.
  • Xcode's iOS simulator. Xcode > Open Developer Tool > iOS Simulator
  • Online tools like BrowserStack

Responsive Images

Images nowadays have to look good on an increasingly wide range of display sizes, from phones to 5K. Retina displays are particularly demanding.

Ideally, we should be able to conditionally load a different image asset based on the device and its connection speed, but web standards are only recently catching up with this problem.

We'll cover responsive images in a little more detail in another lesson, but for now this article details the simplest way to deal with loading images for all sizes (compressive images). Even though this method wastes some extra bandwidth on mobile devices, images that are grossly oversized, but heavily compressed, work better than smaller images of better quality.

Wrapping Up

The bottom line to keep in mind when crafting media queries is keep it simple. Stick to basic queries unless you need to do something special (like resolutions or aspect ratios), and keep the number of queries to a minimum.

Remember: code is read, updated and maintained much more than it is written. And code that's easy to understand when you come back six months later makes everybody happy!