CSS Tutorial / CSS Media Queries and Content-Based Breakpoints
Media queries apply CSS when specified environment conditions are satisfied, such as a viewport width threshold. Choose a breakpoint where the actual content needs a different layout, and account for both component width and surrounding spacing.
Combine baseline and conditional styles
Rules outside media queries supply the baseline. When a condition matches, its declarations join the cascade; they do not delete unrelated baseline declarations. Before adding a breakpoint, check whether fluid sizing can accommodate the content naturally. See Fluid CSS Layouts with min, max, and clamp.
.cards { display: grid; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 33rem) {
.cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
Here, we used the same selector and placed the small branch first, so the subsequent conditional declaration overwrites that property. You should not generalize that “the code below will always win” in all cases. Compare the declaration order when the importance, priority of cascade layer and selector, etc. are the same. If the conditions are true but there is no change, check if a strikethrough appears in other rules in developer tools.
Calculate breakpoints from card requirements
First, check how wide a single card starts to become difficult to read. In practice, the minimum width goal including the border and padding of the card is set to 16rem. This is not a standard value that will fit every site, but is a design requirement for this example. You should try including a long title and description and change it to match the actual font and content.
The content width required for two columns is 33rem, which is 16rem×2 plus 1rem column spacing. If the left and right padding of the text are each 1rem, the required viewport width is 35rem. Therefore, throughout the examples in this lesson, we will start both columns at 35rem. Three columns are 16rem×3 + spacing 1rem×2 + left and right margins 2rem. 52rem is required.
| Columns | card total | Column Spacing Sum | left and right margins | Breakpoint |
|---|---|---|---|---|
| Row 1 | Shrinks to width | 0 | 2rem | default |
| 2nd row | 32rem | 1rem | 2rem | 35rem |
| 3rd row | 48rem | 2rem | 2rem | 52rem |
The reason we don't add the space inside the card back into the table calculation is because we've already included it in our minimum width target of 16rem. Conversely, if the main body divides the width from the sidebar, it is difficult to guarantee card space with just the viewport. In that case, consider recalculating the outer layout conditions or determining the internal layout of the part using the CSS Container Queries for Reusable Components.
Understand rem and inclusive boundaries
min-width is valid when it is equal to or larger than the specified width, and max-width is valid when it is equal to or smaller than the specified width. If your initial font size is 16px, 35rem is 560px and 52rem is 832px. We do not always describe rem as a fixed px value, as the converted value may vary depending on the user's or browser's initial font settings.
The relative length in media queries uses the initial value, not the font size overridden by the page CSS. For example, adding html { font-size: 32px; } to CSS does not automatically make the 35rem condition a 1120px condition. A distinction must be made between changes in rem size of the text and changes in media conditions. This principle is described in the unit-based CSS Media Query specification.
/* Both conditions are true even at 560px. */
@media (max-width: 560px) { /* narrow screen rule */ }
@media (min-width: 560px) { /* wide screen rule */ }
As shown above, min and max conditions with the same boundary overlap at the matching points. You can reduce this problem by adding default and minimum width conditions in stages. The two-column and three-column conditions are also true on large screens, but using the same selector and same properties as in the full example and writing the three-column rule afterwards produces the intended step.
Expand from one to two and three columns
Save it as a media-breakpoint.html file and open it in your browser. No external files are needed. I placed three cards with titles and links, and also added long text to make the text readable even if it was a bit long.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>media-breakpoint.html</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font: 1rem/1.6 sans-serif; color: #243447; }
h1, h2, p { margin-top: 0; } a { color: #145f8f; }
a:focus-visible, button:focus-visible, input:focus-visible { outline: 3px solid #ac4100; outline-offset: 3px; }
.content { width: min(100%, 70rem); margin-inline: auto; padding: 1rem; }
.cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; }
.card { min-width: 0; padding: 1rem; border: 1px solid #789; background: #eef5fa; overflow-wrap: anywhere; }
.card h2 { font-size: 1.25rem; } .card a { display: inline-block; padding: .5rem; }
@media (min-width: 35rem) { .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 52rem) { .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
</style>
</head>
<body>
<main class="content"><h1>Choose breakpoints based on the content</h1>
<p>The target minimum card width is 16rem, including the border and padding.</p>
<div class="cards">
<article class="card"><h2>Files and screen settings to prepare</h2><p>The description and link should follow naturally even when the heading wraps onto several lines.</p><a href="#result">Read the first description</a></article>
<article class="card"><h2>Options for narrow screens</h2><p>Reduce the number of columns to make room instead of simply shrinking the text.</p><a href="#result">Read the second description</a></article>
<article class="card"><h2>English identifier</h2><p>ARTICLE_REFERENCE_WITHOUT_SPACES_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</p><a href="#result">Read the third description</a></article>
</div><p id="result">Check that links and keyboard focus remain visible on the screen.</p></main>
</body>
</html>
Turning off the minimum width for minmax(0, 1fr) and cards prevents columns from growing off-screen due to long content. However, the purpose of this example is to reduce the number of columns rather than forcing only the letters to fit. At the maximum body width of 70rem, the columns do not continue to spread endlessly, but three cards divide the remaining space.
Test immediately around each breakpoint
- Compare 559px, 560px, and 561px in an environment with an initial font size of 16px. 559px should be 1 column, 560px should be 2 columns.
- Compare 831px, 832px, and 833px. 831px should be 2 columns, 832px should be 3 columns. Make sure the card width is at least 16rem even when you reach the exact junction.
- Change only the two column breakpoints from 35rem to 30rem. At 480px, observe if the card width becomes smaller than target and the number of title lines increases, then restore to 35rem.
- Conditions that significantly change the browser default font settings and conditions that only change the CSS html font are recorded. Don't treat it as the same experiment, but double-check the width and card placement in each condition.
Media queries can test orientation, input capabilities, and a preference for reduced motion as well as width. A narrow screen does not necessarily mean a touch device, and a wide screen does not guarantee a mouse. Complete the width-based layout first, then add other conditions where the feature requires them. The MDN guide to using media queries explains their syntax and environment conditions.










