CSS Breakpoints
Media Queries taught how @media fires. Responsive Images taught how pictures fit the slots those queries create. Breakpoints are the plan: a short list of widths where the layout strategy changes — columns, nav, spacing — named once and reused so the whole site moves in step.
A breakpoint toolkit
📊 Breakpoints at a glance
| Piece | Everyday job |
|---|---|
| Breakpoint | A planned width where layout rules change |
| Content-driven choice | Pick widths where the design feels cramped or sparse — not phone SKUs |
Named steps (sm, md, lg…) |
Same token everywhere; easier audits and teamwork |
| Mobile-first ladder | Base = narrow; min-width steps add enhancements |
| Fluid between steps | %, rem, Flex/Grid flex before adding another query |
| Documented set | One short list in comments or tokens — not twenty one-off values |
A breakpoint is not “the iPhone.” It is “when this sidebar no longer fits beside the article” or “when the nav can become a row.” Measure the content, then write one shared step.
Content first — not a device catalog
Resize the browser until something breaks: line length too long, cards crushed, hamburger still needed when space is free. Note that width in rem (or em). That candidate beats copying a marketing table of phone pixels.
/* Break when article + sidebar need two columns (~48rem content width) */
@media (min-width: 48rem) {
.layout {
display: grid;
grid-template-columns: 1fr 16rem;
gap: 1.5rem;
}
}
Pixel-perfect device lists age badly — new phones appear every year. A few content-driven steps stay useful longer and keep stylesheets readable.
Name the steps — reuse the same widths
Pick two to four steps for a typical site. Give them short names in comments (or CSS custom properties holding the width values). Every component that “starts the wide layout” should use the same number — not 720px in the header and 768px in the grid.
:root {
--bp-md: 40rem;
--bp-lg: 64rem;
}
/* Usage still needs a literal in @media in classic CSS —
keep tokens and queries in sync, or use a preprocessor/build step. */
@media (min-width: 40rem) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 64rem) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
}
Classic @media cannot read custom properties as the query condition in all browsers the way you might hope — so treat :root tokens as documentation and JS/tooling helpers, and keep the matching literals consistent. The habit that matters: one shared ladder, not random widths per file.
Mobile-first ladder
Write narrow defaults without queries. Each min-width step adds columns, larger type, or a horizontal nav. Avoid rewriting the entire page at every step — change one clear layer.
.nav {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.card-grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 40rem) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 64rem) {
.nav {
flex-direction: row;
align-items: center;
gap: 1.5rem;
}
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
}
Desktop-first tightening (when you start wide)
If the project already ships a wide layout, max-width queries can collapse columns on smaller viewports. Stay consistent: do not mix random min-width and max-width cutovers for the same component without a reason.
.sidebar {
width: 18rem;
float: left;
margin-right: 1.5rem;
}
@media (max-width: 39.99rem) {
.sidebar {
float: none;
width: auto;
margin-right: 0;
}
}
Prefer one direction per project. Media Queries already covered min-width vs max-width syntax — here the rule is strategy: shared steps, same philosophy everywhere.
One step, many components
When --bp-lg (or 64rem) fires, update nav, grid, and spacing together if they belong to the same layout chapter. Scattered “almost the same” widths create bugs where the header flips before the main grid.
@media (min-width: 64rem) {
.site-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.main {
display: grid;
grid-template-columns: minmax(0, 1fr) 18rem;
gap: 2rem;
}
}
Fluid first — queries second
Between breakpoints, Flex, Grid, %, and rem should already absorb small width changes. Add a new query only when a structural change is required (new column count, different nav pattern). More queries are not more professional.
Try it yourself
- Resize a practice page and list two widths where the layout truly needs a change.
- Convert those widths to
remand name them (md,lg). - Apply the same two
min-widthvalues to both a card grid and the nav. - Search the CSS for other
min-width/max-widthnumbers — merge near-duplicates. - Remove one unnecessary query by improving the fluid base (gap,
minmax, wrapping).
Common mistakes
- Catalog of every phone width instead of content pain points
- Twelve overlapping queries with slightly different pixel values
- Header breaks at
768px, main at800px, footer at720px - Skipping fluid CSS and solving every nudge with another
@media - Re-teaching
@mediabraces orsrcsethere instead of planning the ladder
Summary
- Breakpoints are planned layout steps — name a short set and reuse it
- Choose widths from content stress, not device marketing tables
- Prefer a mobile-first
min-widthladder; keep one direction per project - Stay fluid between steps; query only for structural changes
- This closes the Responsive module — next: Box Shadow in Effects & Motion
🧠 Test Your Knowledge
Test Your Knowledge
Challenge yourself with this interactive quiz and see how well you understand the topic
📝 Instructions
- Read each question carefully
- Select the best answer for each question
- You can retake the quiz as many times as you want
- Your progress will be shown at the top