CSS Media Queries and Responsive Design
By Flavio Copes
Learn how CSS media queries power responsive design, from media types like screen and print to feature descriptors combined with @media to adapt your layouts.
In this post I’m going to first introduce media types and media feature descriptors, then I’ll explain media queries.
Media types
Used in media queries and @import declarations, media types allow us to determine on which media a CSS file, or a piece of CSS, is loaded.
We have the following media types
allmeans all the mediaprintused when printingscreenused when the page is presented on a screenspeechused for screen readers
screen is the default.
In the past we had more of them, but most are deprecated as they proven to not be an effective way of determining device needs.
We can use them in @import statements like this:
@import url(myfile.css) screen;
@import url(myfile-print.css) print;
We can load a CSS file on multiple media types separating each with a comma:
@import url(myfile.css) screen, print;
The same works for the link tag in HTML:
<link rel="stylesheet" type="text/css" href="myfile.css" media="screen" />
<link rel="stylesheet" type="text/css" href="another.css" media="screen, print" />
We’re not limited to just using media types in the media attribute and in the @import declaration. There’s more
Media feature descriptors
First, let’s introduce media feature descriptors. They are additional keywords that we can add to the media attribute of link or to the @import declaration, to express more conditionals over the loading of the CSS.
Here’s the list of them:
widthheightaspect-ratiocolorcolor-indexmonochromeresolutionorientationscangridprefers-color-scheme(light/dark preference)prefers-reduced-motion
These older device-* features are deprecated. Use width, height and aspect-ratio instead:
device-width(deprecated)device-height(deprecated)device-aspect-ratio(deprecated)
The ones that take a length, a number or a ratio have a corresponding min-* and max-*, for example:
min-width,max-widthmin-height,max-height
min-device-width / max-device-width and the other *-device-* forms are deprecated too. Stick to min-width / max-width when you pick breakpoints.
Some of those accept a length value which can be expressed in px or rem or any length value. It’s the case of width and height.
For example:
@import url(myfile.css) screen and (max-width: 800px);
Notice that we wrap each block using media feature descriptors in parentheses.
Some accept a fixed value. orientation, used to detect the device orientation, accepts portrait or landscape.
Example:
<link rel="stylesheet" type="text/css" href="myfile.css" media="screen and (orientation: portrait)" />
scan, used to determine the type of screen, accepts progressive (for modern displays) or interlace (for older CRT devices)
Some others want an integer.
Like color which inspects the number of bits per color component used by the device. Very low-level, but you just need to know it’s there for your usage (like grid, color-index, monochrome).
aspect-ratio accepts a ratio value representing the width to height viewport ratio, which is expressed as a fraction. Prefer it over the deprecated device-aspect-ratio.
Example:
@import url(myfile.css) screen and (aspect-ratio: 4/3);
resolution represents the pixel density of the device, expressed in a resolution data type like dpi.
Example:
@import url(myfile.css) screen and (min-resolution: 100dpi);
Logic operators
We can combine rules using and:
<link rel="stylesheet" type="text/css" href="myfile.css" media="screen and (max-width: 800px)" />
We can perform an “or” type of logic operation using commas, which combines multiple media queries:
@import url(myfile.css) screen, print;
We can use not to negate a media query:
@import url(myfile.css) not screen;
Important:
notcan only be used to negate an entire media query, so it must be placed at the beginning of it (or after a comma)
Media queries
All those above rules we saw applied to @import or to the link HTML tag can be applied inside the CSS, too.
You need to wrap them in a @media () {} structure.
Example:
@media screen and (max-width: 800px) {
/* enter some CSS */
}
and this is the foundation for responsive design.
For font sizes, clamp() can scale values fluidly without media queries: try my free clamp() calculator to generate the CSS.
Media queries can be quite complex. This example applies the CSS only if it’s a screen device, the width is between 600 and 800 pixels, and the orientation is landscape:
@media screen and (max-width: 800px) and (min-width: 600px) and (orientation: landscape) {
/* enter some CSS */
}Want me to talk about your product? You can sponsor this site.