Why responsive design matters
With internet-capable devices spanning an ever-wider range of screen sizes, sites need layouts that work everywhere from a phone in portrait mode to a widescreen monitor. Responsive web design, a strategy popularized by Ethan Marcotte, meets that need by adapting a site's layout to the device in use: a single column on a phone, two on a tablet, and three or four on a desktop. Modern responsive design also factors in how users interact with a device, such as touchscreens, with the goal of optimizing the experience for everyone.
Control the viewport
Mobile browsers try to render pages at a desktop width (often around 980px) and then scale content down to fit the screen, which can produce inconsistent font sizes and force users to zoom. To take control, include a meta viewport tag in the document <head>.
Setting width=device-width matches the page to the screen's width in device-independent pixels (DIPs), allowing content to reflow for different screen sizes. Adding initial-scale=1 establishes a 1:1 relationship between CSS pixels and DIPs, so a page reflows rather than zooming when a device rotates to landscape. The Lighthouse audit "Does not have a <meta name="viewport"> tag with width or initial-scale" can help automate checking that your documents include the tag correctly.
Fit content to the viewport
Users expect to scroll vertically, not horizontally. Content that exceeds the viewport width forces awkward horizontal scrolling or zooming out, which is a poor experience. Images are a common culprit: an image wider than the viewport will trigger horizontal scrolling.
Set images to shrink to fit their container with a maximum width of 100%:
img {
max-width: 100%;
}
Even when using max-width: 100%, add width and height attributes to your <img> tags so the browser can reserve space before the image loads, which helps minimize layout shifts. The Lighthouse audit "Content is not sized correctly for the viewport" can detect overflowing content automatically.
Flexible layouts
Because CSS pixel widths vary so much between devices, layouts should not depend on a particular viewport width. Fixed pixel measurements force horizontal scrolling on small screens; percentage-based widths let columns shrink proportionally.
Modern CSS techniques make these fluid grids easier than the older float-based approaches:
- Flexbox lays out items of different sizes in a single row or wraps them onto multiple rows as space shrinks, letting larger items take more room.
- CSS Grid with the
frunit distributes available space across tracks. You can also create grids with as many items as fit, reducing the number of tracks as the screen narrows, for example by setting a minimum track size like200px. - Multiple-column Layout (Multicol) with
column-widthadds columns responsively; for instance, the page adds another200pxcolumn whenever there's room for it.
Go further with media queries
Fluid grids handle many cases, but sometimes you need more extensive layout changes for certain screen sizes. Media queries act as filters that apply styles conditionally, based on device features such as width, height, and orientation, or the type of device rendering the content.
You can target output types to provide print-specific styles, either in a separate stylesheet:
<link rel="stylesheet" href="print.css" media="print">
Or inside your main style sheet:
@media print {
/* print styles here */
}
Queries for viewport size
To create a responsive experience that changes layout by screen dimensions, media queries can test for width and height (including their min- and max- variants), as well as orientation and aspect-ratio.
Queries for device capability
Screen size alone doesn't tell you how a user is interacting. Not every large device is a desktop, and not every small device is touch-only. Newer media features test interaction capabilities:
hoverpointerany-hoverany-pointer
The hover and pointer features describe the primary input. Use the any- variants carefully: any-hover and any-pointer check whether the user has a pointing device that can hover, even if it's not the primary input, which is well supported in modern browsers. These are useful when you need to know what kind of device someone is using, for instance a touchscreen laptop that matches both coarse and fine pointers and supports hovering. But avoid using them to force touchscreen users away from their device's natural interaction model.
Choosing Breakpoints Based on Content
Breakpoints should not be tied to specific devices, brands, or operating systems. Such an approach quickly becomes unmaintainable as new devices appear. Instead, let your content dictate where the layout needs to change to fit its container.
Start Small and Scale Up
The most effective strategy is to design for a small screen first. Once the content fits well on a narrow viewport, gradually expand the screen width until the layout begins to look stretched or uncomfortable. That point of visual discomfort is where a breakpoint becomes necessary. This "mobile-first" approach keeps the total number of breakpoints low and ensures each one serves a real purpose.
Using the weather forecast widget as an example, you first focus on making it look clean on a small screen:
Next, widen the browser window. You will eventually reach a width where the whitespace between elements becomes excessive—typically above 600px—and the widget loses its visual cohesion.
To address this, add two media queries at the end of your component's CSS. One handles the layout at 600px or narrower, and the other handles widths above 600px:
@media (max-width: 600px) {
}
@media (min-width: 601px) {
}
Finally, refactor the CSS. Place the styles intended for smaller viewports inside the max-width: 600px query, and move the styles for larger viewports into the min-width: 601px query.
Add Minor Breakpoints for Fine-Tuning
Major breakpoints handle significant layout shifts, but you will also want to make subtle adjustments between them. For example, you might increase an element's font size, adjust its padding, or alter margins to improve the overall feel as the viewport grows.
This can be done in stages. First, boost the font size when the viewport exceeds 360px. Then, once there is ample space—for instance, to place the high and low temperatures on the same line—introduce another breakpoint to change the layout and enlarge the weather icons:
@media (min-width: 360px) {
body {
font-size: 1.0em;
}
}
@media (min-width: 500px) {
.seven-day-fc .temp-low,
.seven-day-fc .temp-high {
display: inline-block;
width: 45%;
}
.seven-day-fc .seven-day-temp {
margin-left: 5%;
}
.seven-day-fc .icon {
width: 64px;
height: 64px;
}
}
For very large screens, it is wise to cap the maximum width of the forecast panel so that it doesn't stretch across the entire viewport. This keeps the content scannable and visually balanced:
@media (min-width: 700px) {
.weather-forecast {
width: 700px;
}
}
Optimize Text for Readability
Readability theory suggests an ideal line length holds between 70 and 80 characters—roughly 8 to 10 English words. A useful guideline is to add a breakpoint whenever a block of text begins to exceed about 10 words per line.
For instance, with the Roboto font at 1em, you might achieve 10 words per line on a smaller screen. On a wider screen, that ratio breaks down, calling for a breakpoint. In this scenario, when the browser width is greater than 575px, the optimal content width becomes 550px:
@media (min-width: 575px) {
article {
width: 550px;
margin-left: auto;
margin-right: auto;
}
}
Don't Hide Content to Fit Screen Size
Think carefully before deciding to hide or show content based on viewport size. Users on smaller screens still want access to the same information as those on desktop monitors. Removing content solely because it doesn't fit can be a real problem: for example, hiding the pollen count from a weather widget could prevent allergy sufferers from making crucial decisions about going outside.
Inspecting Breakpoints in Chrome DevTools
Once your breakpoints are in place, you can verify their visual impact. While manually resizing the browser window works, Chrome DevTools provides a more precise method to test your page at specific breakpoints.
To inspect your page at different breakpoints:
- Open DevTools.
- Activate Device Mode, which starts in responsive mode.
- Access the Device Mode menu and select Show media queries. Your breakpoints appear as colored bars above the page.
- Click a bar to see your page with that query active. Right-click a bar to jump directly to that media query's definition in your CSS.



