As the number of mobile phone users on the internet increases, it has become more and more important for web designers to lay out content in ways that work well for a variety of screen sizes. Responsive web design, originally defined by Ethan Marcotte in A List Apart, is a design strategy that responds to users' needs and their devices' capabilities by changing a site's layout to suit the device being used. For example, a responsive site might show content in a single-column view on a phone, two columns on a tablet, and three or four columns on a desktop computer.
Because internet-capable devices have so many possible screen sizes, it's important for your site to adapt to any existing or future screen size. Modern responsive design also accounts for modes of interaction such as touch screens. The goal is to optimize the experience for everyone.
Set the viewport
Pages optimized for a variety of devices must include a meta viewport tag in the head of the document. This tag tells the browser how to control the page's dimensions and scaling.
To try to provide the best experience, mobile browsers render the page at a
desktop screen width (usually about 980px
, though this varies across devices),
and then try to make the content look better by increasing font sizes and
scaling the content to fit the screen. This can make fonts look inconsistent and
require users to zoom in to see and interact with the content.
<!DOCTYPE html>
<html lang="en">
<head>
…
<meta name="viewport" content="width=device-width, initial-scale=1">
…
</head>
…
Using the meta viewport value width=device-width
tells the page to match the
screen's width in device-independent pixels (DIP), a standard visual pixel unit
(which can be made up of many physical pixels on a high-density screen). This
lets the page reflow content to match different screen sizes.
Some browsers keep the
page's width constant when rotating to landscape mode, and zoom to fill the
screen instead of reflowing. Adding the value initial-scale=1
tells browsers
to set a 1:1 relationship between CSS pixels and device-independent pixels
regardless of device orientation, letting the page take advantage of the full
landscape width.
The Does not have a <meta name="viewport">
tag with width
or initial-scale
Lighthouse audit can help you automate the process of making sure your HTML
documents use the viewport meta tag correctly.
Size content to the viewport
On both desktop and mobile devices, users are used to scrolling websites vertically but not horizontally. Forcing the user to scroll horizontally or to zoom out to see the whole page causes a poor user experience.
When developing a mobile site with a meta viewport tag, it's common to accidentally create page content that doesn't quite fit within the specified viewport. For example, an image displayed wider than the viewport can cause horizontal scrolling. To prevent this, adjust your content to fit inside the viewport.
The Content is not sized correctly for the viewport Lighthouse audit can help you automate the process of detecting overflowing content.
Images
An image with fixed dimensions causes the page to scroll if it's larger than the
viewport. We recommend giving all images a max-width
of 100%
, which shrinks
images to fit the available space while preventing them from stretching beyond
their initial size.
In most cases, you can do this by adding the following to your style sheet:
img {
max-width: 100%;
display: block;
}
Add the dimensions of the image to the img element
Even when you set max-width: 100%
, we still recommend adding width
and
height
attributes to your <img>
tags so the browser can reserve space for
images before they load. This helps prevent layout shifts.
Layout
Because screen dimensions and width in CSS pixels vary widely between devices (for example, between phones and tablets, and even between different phones), content shouldn't rely on a particular viewport width to render well.
In the past, this required setting layout elements in percentages. Using pixel measurements requires the user to scroll horizontally on small screens:
Using percentages instead makes the columns narrower on smaller screens, because each column always takes up the same percentage of the screen width:
Modern CSS layout techniques such as Flexbox, Grid Layout, and Multicol make creating these flexible grids much easier.
Flexbox
Use Flexbox when you have a set of items of different sizes and you want them to fit comfortably in a row or multiple rows, with smaller items taking up less space and larger ones taking more space.
.items {
display: flex;
justify-content: space-between;
}
You can use Flexbox to display items as a single row, or wrapped onto multiple rows as the available space decreases.
CSS Grid Layout
CSS Grid Layout creates flexible grids. You can improve the earlier floated
example using use grid layout and the fr
unit, which represents a portion of
the available space in the container.
.container {
display: grid;
grid-template-columns: 1fr 3fr;
}
You can also use Grid Layout to create regular grid layouts with as many items
as can fit. The number of available tracks is reduced as the screen size
decreases. The following demo shows a grid containing as many cards as fit on
each row, with a minimum size of 200px
.
Read more about CSS Grid Layout
Multiple-column layout
For some types of layout, you can use Multiple-column Layout (Multicol),
which creates responsive numbers of columns with the column-width
property.
In the following demo, the page adds columns when there's
room for another 200px
column.
Use CSS media queries for responsiveness
Sometimes you might need to make more extensive changes to your layout to support certain screen sizes than the techniques described previously allow. This is where media queries become useful.
Media queries are simple filters that you can apply to CSS styles, to change those styles based on the types of device rendering the content. They can also change styling based on device features including width, height, orientation, and whether the device is being used as a touchscreen.
To provide different styles for printing, you can target an output type and include a style sheet for print styles:
<!DOCTYPE html>
<html lang="en">
<head>
…
<link rel="stylesheet" href="print.css" media="print">
…
</head>
…
You can also use a media query to include print styles in your main style sheet:
@media print {
/* print styles go here */
}
For responsive web design, the most common queries are for device features, so you can customize your layout for touchscreens or smaller screens.
Media queries based on viewport size
Media queries let you create a responsive experience that applies specific styles to specific screen size. Queries for screen size can test for the following things:
width
(min-width
,max-width
)height
(min-height
,max-height
)orientation
aspect-ratio
All of these features have excellent browser support. For more details, including browser support information, see width, height, orientation, and aspect-ratio on MDN.
Media queries based on device capability
Given the range of devices available, developers can't assume that every large device is a regular desktop or laptop computer, or that every small device uses a touchscreen. Some newer additions to the media queries specification let you test for features such as the type of pointer used to interact with the device and whether the user can hold a pointer over elements.
hover
pointer
any-hover
any-pointer
Try viewing this demo on different devices, such as a regular desktop computer and a phone or tablet.
These newer features have good support in all modern browsers. Find out more on the MDN pages for hover, any-hover, pointer, and any-pointer.
Use any-hover
and any-pointer
The features any-hover
and any-pointer
test if the user can hold a pointer
over elements (often called hovering), or use a pointer at all, even if it's
not the primary way they interact with their device. Be very careful when using
these, for example to avoid forcing a touchscreen user to switch to a mouse.
However, any-hover
and any-pointer
can be useful if it's important to
determine what kind of device a user has. For example, a laptop with a
touchscreen and trackpad should match coarse and fine pointers, in addition to
the ability to hover.
How to choose breakpoints
Don't define breakpoints based on device classes, or any product, brand name, or operating system. This makes your code difficult to maintain. Instead, let the content determine how its layout changes to fit the container.
Pick major breakpoints by starting small, then working up
Design the content to fit on a small screen size first, then expand the screen until a breakpoint becomes necessary. This lets you minimize the number of breakpoints on your page and optimize them based on content.
The following example walks through the weather forecast widget example at the beginning of this page. The first step is to make the forecast look good on a small screen:
Next, resize the browser until there's too much whitespace between the elements
to make the widget look good. The decision is subjective, but more than 600px
is certainly too wide.
To insert a breakpoint at 600px
, create two media queries at the end of your
CSS for the component: one to use when the browser is 600px
or narrower, and
one for when it's wider than 600px
.
@media (max-width: 600px) {
}
@media (min-width: 601px) {
}
Finally, refactor the CSS. Inside the media query for a max-width
of 600px
,
add the CSS which is only for small screens. Inside the media query for a
min-width
of 601px
add CSS for larger screens.
Pick minor breakpoints when necessary
In addition to choosing major breakpoints when layout changes significantly, it's also helpful to adjust for minor changes. For example, between major breakpoints it can be helpful to adjust the margins or padding on an element, or increase the font size to make it feel more natural in the layout.
This example follows the same pattern as the previous one, starting with
optimizing smaller screen layouts. First, boost the font when the viewport
width is greater than 360px
. After that, when there's enough space, you can
separate the high and low temperatures so they're on the same line, and make the
weather icons larger.
@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 large screens, we recommend limiting the maximum width of the forecast panel so it doesn't use the whole screen width.
@media (min-width: 700px) {
.weather-forecast {
width: 700px;
}
}
Optimize text for reading
Classic readability theory suggests that an ideal column should contain 70 to 80 characters per line (about 8 to 10 words in English). Consider adding a breakpoint every time the width of a text block grows past about 10 words.
In this example, the Roboto font at 1em
produces 10 words per line on the
smaller screen, but larger screens need a breakpoint. In this case, if the
browser width is greater than 575px
, the ideal content width is 550px
.
@media (min-width: 575px) {
article {
width: 550px;
margin-left: auto;
margin-right: auto;
}
}
Avoid hiding content (:#avoid-hiding-content)
Be careful when choosing what content to hide or show depending on screen size. Don't hide content just because you can't fit it on the screen. Screen size doesn't predict what a user might want to see. For example, removing the pollen count from the weather forecast could be a serious issue for springtime allergy sufferers who need that information to decide whether they can go outside.
View media query breakpoints in Chrome DevTools
After you set up your media query breakpoints, check how they affect your site's appearance. You could resize your browser window to trigger the breakpoints, but Chrome DevTools has a built-in feature that shows how a page looks under different breakpoints.
To view your page under different breakpoints:
- Open DevTools.
- Turn on Device Mode. This opens in responsive mode by default.
- To see your media queries, open the Device Mode menu and select Show media queries. This shows your breakpoints as colored bars above your page.
- Click one of the bars to view your page while that media query is active. Right-click a bar to jump to that media query's definition.