CSS Media Queries
CSS media queries apply styles when specified conditions are true. They are an important part of responsive web design because they allow a layout to adapt to different viewport sizes and other device or user characteristics.
A media query can test features such as width, height, orientation, pointer capabilities, and user preferences. When the condition matches, the CSS rules inside the query are applied.
How Media Queries Work
A media query contains a condition followed by a block of CSS rules. The rules are applied only when the condition evaluates to true.
@media (max-width: 600px) {
.content {
padding: 10px;
}
}
In this example, the smaller padding is applied when the viewport width is 600 pixels or less.
When the condition does not match, the declarations inside the media query do not participate in styling the element.
Media Query Syntax
A media query is created with the CSS @media at-rule.
@media (condition) {
/* CSS rules */
}
The condition can test one or more media features. A common responsive design query tests the viewport width.
@media (min-width: 768px) {
.container {
width: 90%;
}
}
The enclosed rule applies when the viewport is at least 768 pixels wide.
Width Media Queries
Viewport width is one of the most commonly tested features in responsive web design.
@media (width <= 600px) {
.navigation {
display: block;
}
}
This query matches when the viewport width is 600 pixels or less.
Width queries are commonly used to change layouts, spacing, navigation, typography, and other presentation details when the available space changes.
Responsive Breakpoints
A breakpoint is a width or other condition at which a responsive design changes its presentation.
@media (min-width: 768px) {
.cards {
grid-template-columns: repeat(2, 1fr);
}
}
In this example, 768 pixels is the breakpoint where the card layout changes to two columns.
Breakpoints should be chosen according to the needs of the content and layout rather than simply targeting particular phones, tablets, or desktop devices.
Using min-width
A min-width media query applies styles when the viewport is equal to or wider than the specified value.
.cards {
display: grid;
grid-template-columns: 1fr;
}
@media (min-width: 700px) {
.cards {
grid-template-columns: repeat(2, 1fr);
}
}
The layout begins with one column. When the viewport reaches 700 pixels, it changes to two columns.
This pattern works naturally with a mobile-first approach because the basic styles are written first and enhancements are added as more space becomes available.
Using max-width
A max-width media query applies styles when the viewport is equal to or narrower than the specified value.
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 700px) {
.cards {
grid-template-columns: 1fr;
}
}
Here the layout begins with three columns and changes to one column when the viewport becomes 700 pixels wide or narrower.
Both min-width and max-width are valid techniques. The next tutorial explains the mobile-first approach in more detail.
Media Query Range Syntax
Modern media queries can use comparison operators to express width and other range conditions.
@media (width >= 768px) {
.content {
padding: 2rem;
}
}
This is equivalent in purpose to a min-width: 768px query.
A range can also specify both a lower and upper boundary.
@media (600px <= width <= 1000px) {
.content {
width: 90%;
}
}
This query matches when the viewport width is between 600 and 1000 pixels, including both boundaries.
Combining Media Conditions
The and keyword requires multiple conditions to match.
@media (min-width: 600px) and (max-width: 1000px) {
.content {
width: 90%;
}
}
The styles apply only when both width conditions are true.
A comma separates multiple media queries and acts like an OR condition. The styles apply when any query in the list matches.
@media (max-width: 600px), (orientation: portrait) {
.content {
padding: 1rem;
}
}
The not keyword can negate a media query, although straightforward positive conditions are often easier to understand and maintain.
Orientation Media Queries
The orientation media feature tests whether the viewport is wider than it is tall or at least as tall as it is wide.
@media (orientation: landscape) {
.gallery {
grid-template-columns: repeat(3, 1fr);
}
}
The landscape value matches when the viewport width is greater than its height. The portrait value matches when the viewport height is greater than or equal to its width.
Orientation describes the viewport's dimensions. It should not be treated as a reliable way to identify a particular type of physical device.
Media Types
Media queries can also specify a media type. The most commonly useful types are screen and print.
@media print {
.navigation {
display: none;
}
}
This rule hides the navigation when the document is printed.
The all media type applies to all devices and is the default when a media type is omitted.
@media screen and (min-width: 800px) {
.content {
max-width: 1200px;
}
}
User Preference Media Features
Media queries are not limited to viewport dimensions. They can also respond to certain preferences selected by the visitor in their operating system or browser environment.
@media (prefers-reduced-motion: reduce) {
.animated {
animation: none;
}
}
The prefers-reduced-motion feature can be used to reduce or remove nonessential motion for visitors who request it.
Other preference-related media features include prefers-color-scheme and prefers-contrast. These queries can help a design respond to user preferences instead of only responding to screen dimensions.
Choosing Breakpoints
Responsive breakpoints should be based on where the content or layout needs to change.
Start with the layout and resize the viewport. When content becomes crowded, lines become difficult to read, navigation no longer fits, or a layout would work better in a different arrangement, that point can indicate a useful breakpoint.
This approach is more flexible than creating breakpoints around specific device models because screen sizes and browser window dimensions vary widely.
| Consider | Possible Response |
|---|---|
| Navigation becomes crowded | Change the navigation layout. |
| Cards become too narrow | Reduce the number of columns. |
| Content becomes too wide | Apply or adjust a maximum width. |
| Spacing becomes excessive | Reduce padding or gaps. |
CSS Media Query Example
The following example starts with a one-column layout and changes to three columns when the available viewport reaches 650 pixels.
.cards {
display: grid;
grid-template-columns: 1fr;
gap: 15px;
}
@media (min-width: 650px) {
.cards {
grid-template-columns: repeat(3, 1fr);
}
}
Open the example in the editor and change the 650px breakpoint. Drag the divider between the code and result panes to change the preview width and see exactly when the layout changes.
