RWD Media Query Basics

A media query is a CSS rule that only applies its styles when a condition about the browsing environment, most commonly the viewport's width, is true.

What Is a Media Query?

Everything covered so far, fluid grids, percentage widths, flexible images, lets a layout stretch and shrink smoothly. But sometimes stretching isn't enough, at some point three columns squeezed onto a 360px phone screen become too narrow to read no matter how flexible the CSS is. Media queries solve this by letting you write CSS rules that only take effect when the browser matches a certain condition, most often 'the viewport is at most this many pixels wide' or 'at least this many pixels wide'. This lets you restructure the layout itself, for example switching from three columns to one, rather than just shrinking it.

Example

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.sidebar {
  width: 25%;
  float: left;
}

@media (max-width: 768px) {
  .sidebar {
    width: 100%;
    float: none;
  }
}
</style>
</head>
<body>

</body>
</html>
  • @media is the keyword that starts a media query
  • (max-width: 768px) is the condition, here meaning 'viewport width is 768px or less'
  • The CSS rules inside the curly braces only apply when that condition is true
  • Everything outside the media query still applies as the normal, default styling

max-width and min-width are the two conditions used constantly in RWD. A max-width: 768px query applies its styles at 768px and any width narrower than that, so it's useful for 'shrink down for small screens' rules. A min-width: 768px query applies at 768px and any width wider than that, useful for 'add more layout once there's enough room' rules. Which one you reach for first, by default, defines whether you're working mobile-first or desktop-first, a distinction covered in depth on its own page.

Example

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.card {
  padding: 12px;
}

@media (min-width: 768px) {
  .card {
    padding: 24px;
  }
}
</style>
</head>
<body>

</body>
</html>
Media featureWhat it checks
width / max-width / min-widthThe viewport's width
height / max-height / min-heightThe viewport's height
orientationportrait or landscape
aspect-ratioRatio of viewport width to height
prefers-color-schemeWhether the user's OS is set to light or dark mode

Combining Multiple Conditions

Conditions can be combined with the keyword and to require every condition to be true at once, which is how you target a specific range like 'tablet-sized screens only'. A comma between queries works like a logical or, applying the styles if either query matches. There's also a not keyword to invert an entire query.

Example

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
/* Applies only between 600px and 900px, a typical tablet range */
@media (min-width: 600px) and (max-width: 900px) {
  .layout {
    grid-template-columns: repeat(2, 1fr);
  }
}
</style>
</head>
<body>

</body>
</html>
Note: When you need a range like 'between 600px and 900px', combine min-width and max-width with and, as shown above, rather than writing two separate overlapping queries, which is easy to get wrong.
Note: Newer CSS also supports a more compact range syntax, @media (600px <= width <= 900px), which reads closer to plain math. It's supported in all current major browsers, but if you need to support older browsers the min-width/max-width and syntax above is the safer, more universally understood choice.