CSS course menu
CSS Media Queries: Breakpoints, min-width, max-width and Media Features
Learn CSS media queries: the @media syntax, min-width and max-width breakpoints, range syntax, combining conditions, orientation, hover and pointer for touch devices, prefers-reduced-motion and prefers-color-scheme, and print styles.
On this page
A media query applies CSS only when a condition about the device or browser is true: the screen is at least a certain width, the user prefers dark mode, the page is being printed, and so on.
Syntax#
@media (min-width: 768px) {
.sidebar { display: block; }
}The rules inside the block apply only when the condition in parentheses is true. Everything else in the stylesheet still applies as usual.
Width breakpoints#
.banner { padding: 12px; color: white; font: 600 16px system-ui, sans-serif; background: #e8590c; }
.banner::after { content: "narrow (under 500px)"; }
@media (min-width: 500px) {
.banner { background: #2f5fe0; }
.banner::after { content: "wide (500px or more)"; }
}<div class="banner">This frame is </div>
<p>Make your browser window narrower or wider to change it.</p>Inside this lesson's Result frames, "width" means the width of the frame, which follows the lesson column.
The range syntax is clearer and is supported in current versions of all major browsers.
Mobile first or desktop first#
/* Mobile first: base styles for small screens, then add */
.grid { display: grid; gap: 1rem; }
@media (min-width: 700px) { .grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1100px) { .grid { grid-template-columns: repeat(3, 1fr); } }With mobile-first min-width queries, put the queries in increasing order, so larger screens override smaller ones. Desktop-first max-width queries go in decreasing order. Pick one approach per project; mixing both leads to gaps and overlaps.
Combining conditions#
@media (min-width: 600px) and (max-width: 899px) { } /* both must be true */
@media (orientation: landscape), (min-width: 1200px) { } /* comma: either one */
@media not print { } /* everything except printing */Media features beyond width#
/* Only add hover effects on devices that can hover */
@media (hover: hover) {
.card:hover { transform: translateY(-2px); }
}
/* Larger tap targets for touch screens */
@media (pointer: coarse) {
.toolbar button { min-height: 44px; min-width: 44px; }
}
/* Respect users who get dizzy or distracted by motion */
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
}Print styles#
The print media type applies when a page is printed or saved as PDF:
@media print {
nav, .ads, .comments, button { display: none; }
body { font-size: 12pt; color: black; background: white; }
a[href^="http"]::after { content: " (" attr(href) ")"; }
}Hiding navigation and showing link URLs makes printed articles far more useful. Preview it with your browser's Print dialog.
Where to write media queries#
You can keep each query next to the component it changes (easy to maintain), or collect them at the end of the stylesheet. Both work; the order rule above is what matters. Media queries can also go in the HTML, on a <link>:
<link rel="stylesheet" href="print.css" media="print">Practice#
Practice exercise
Write mobile-first CSS for a .cards container: one column by default, two columns from 600px, four columns from 1000px. Add hover lift effects only on devices that support hover, and turn off all transitions for users who prefer reduced motion.
Show solution
.cards { display: grid; gap: 1rem; }
@media (min-width: 600px) {
.cards { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1000px) {
.cards { grid-template-columns: repeat(4, 1fr); }
}
.card { transition: transform 0.2s; }
@media (hover: hover) {
.card:hover { transform: translateY(-4px); }
}
@media (prefers-reduced-motion: reduce) {
.card { transition: none; }
}Key takeaway#
Finished this lesson?