At-media queries are conditions in your stylesheet. The style rules they contain are applied only if certain criteria are met, such as device width, resolution, or browser window dimensions.
Media queries can be written inside a stylesheet, or may be the conditions for using the CSS in an external stylesheet. We‘ll start by exploring the first, and most common, application.
@media rules
Most stylesheets begin with fundamental declarations that are true in all conditions:
@charset utf-8
@font-face {
font-family: 'Mallory';
src: url('Mallory-Light.woff2') format('woff2');
font-style: normal;
font-weight: 300;
}
* {
box-sizing: border-box;
}
body {
font-family: Mallory, Gill Sans, sans-serif;
background: hsl(240, 67%, 94%);
color: black;
}
Working from this stylesheet, let‘s say we wanted to improve text contrast at smaller window sizes. We could add an @media
rule to cover this condition by adding the following:
@media all and (max-width: 600px) {
body {
background: #000;
color: #fff;
}
}
If you test the resulting page, you‘ll see the background and text color change when the browser window narrows to 600px wide or less.
There are a few important things to note at this stage:
@media
rules work in addition to other aspects of responsive design, including fluid images.- The declarations inside the
@media
rule contain only the things that are altered if the conditions are met. Do not attempt to rewrite the entire stylesheet inside an@media
rule. Only the things that change are added; the base rules that are not affected by the new declarations will still apply under the new conditions. - The
@media
rule uses curly braces to contain the declarations. You can have as many declarations inside the@media
rule as you like. You can also have as many@media
rules as you wish, although obviously the more you add, the more complex your CSS becomes. - In general practice you should usually write your base CSS first in your stylesheet, i.e. the styles that will remain the same under all (or most) conditions, adding the
@media
rules at the end.
Due to the slightly more complex syntax of @media
queries, it makes sense to test that they work first with something dramatic like a background color change, especially when you are just beginning to learn and apply them.
Syntax
The first part of the @media
rule above – the all
– states what kind of media the rule is applied to. all
means exactly that: the declarations will be valid for every form of media, provided the condition (and (max-width: 600px)
) is met.
Associating conditions with an @media
rule is optional. How a web page will be printed out is often specified in a rule like this, without any further conditions:
@media print {
/* rules for a print stylesheet here */
}
Other options for @media
include screen
(intended for color screens) and speech
for speech synthesisers).
min-width and max-width
The two most common conditions associated with all
or screen
are and (min-width: x)
and and (max-width: x)
. Both measure the browser viewport width, and are usually the most straightforward way of determining it‘s size.
It‘s easy to get min-width
and max-width
confused; thankfully, there‘s also an easy way to remember which is which.
min-width
means “the browser window must be at least this width or greater”max-width
means “the browser can be up to this width or smaller”
You‘ll typically use one or the other in your stylesheet; it‘s rare (and usually confusing) to use both. Which one you use comes down to your design approach:
- if you are using a mobile-first approach, then you are writing your base CSS for the smallest browser width, and adding adjustments to it as the browser widens with
@media all and (min-width: x) { }
. - if you take a desktop-first approach, then you are writing your CSS for what appears on your monitor and adjusting it as the browser narrows using
@media all and (max-width: x) { }
.
Units
Technically, the measurement defined for min-width
and max-width
can use almost any CSS length unit, with the exception of vw
, vh
, vmin
or vmax
. Using pixels is common, but comes with some caveats:
- Pixels are not what you think they are in CSS. For example, the resolution for the product specs of the iPhone are not a direct part of the calculations for
min-width
andmax-width
. - It‘s best to ignore device sizes. People tend to become obsessed with the exact pixel dimensions of the browser in the iPhone XIII, or whatever their mobile device is. That is a fool‘s errand: you‘ll constantly be chasing new mobile releases to update your stylesheet, and inevitably ignore other devices. Instead, write
@media
rules as interventions where the design of your site needs them. By making the browser window wider or narrower, you can find where your particular design “breaks”, and intervene at that point, an approach that will work for every device.
combinators
You‘ve already seen one combinator in an @media
query: and
. It‘s also possible to use not
and only
and a comma delimiter:
@media only screen {
…
}
Or:
@media screen, print {
…
}
You can use and
and or
as many times as you wish to chain together conditions:
@media screen and (max-width: 600px)
and (min-resolution: 200dpi) {
…
}
There are many conditions that can be added in an @media
query, but it is always recommended to start with the basics first.
Variations
As mentioned at the start of this article, it‘s also possible to write media queries inside link
elements:
<link rel="stylesheet" href="styles_h.css"
media="only screen and (max-width: 480px)">
Contrary to expectations, media
conditions do not prevent the browser from loading the stylesheet. The browser loads the file regardless, but it does not use the CSS in the stylesheet unless it matches the associated conditions.
Conditions, Limitations and Conclusions
As powerful as they are, @media
queries do have a few limitations that you should be aware of:
- Currently
@media
inspects conditions in the browser viewport and device, not the state of individual elements. So-called “element queries” are planned for CSS; right now, a JavaScript polyfill is recommended to create the functionality. @media
queries can‘t use CSS variables in their conditions, nor can they be nested inside elements. If you want those kinds of features, use Sass or another CSS pre-processor.
Photograph by Jeremy Keith used under a Creative Commons Attribution 2.0 Generic license
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.