Skip to contentSkip to footer

If you want to be kept up to date with new articles, CSS resources and tools, join our newsletter.

Creating a responsive design can be intimidating. There are many moving parts, things might lay out in ways you didn't expect and keeping all various viewports in mind when laying out a design can be daunting. With these ground rules, your responsive designs will be more robust and predictable.

Video

Prefer a video? We recently discussed these ground rules in a 30 minute presentation for Mintbean:

Rule #1: Keep your viewport simple

Back when the viewport meta tag was first introduced, common knowledge was you had to add in all sorts of values to prevent users from resizing and to have a minimum and maximum screen size. It turns out that doing that is actually hostile to your users.

You really only want two things: set the width to the device your site is shown on, and make sure the initial scale is 1, which means that 1 pixel in your CSS equals one device-independent pixel (and also prevent weird zooming behaviour when rotating mobile devices), like this:

<meta name="viewport" content="width=device-width" />

There are two things you can consider adding:

<meta name="viewport" content="width=device-width, initial-scale=1" />

initial-scale=1 will prevent mobile browsers from zooming out if you have horizontal overflow issues, instead opting for a horizontal scrollbar. Neither is ideal and the true fix is fixing the overflow issue, but between the two I prefer showing the page at the intended zoom level.

<meta name="viewport" content="width=device-width, viewport-fit=cover" />

viewport-fit=cover will tell mobile browsers that your site knows about devices with notches or other device-parts that seem to "overlay" the screen. This will make sure your site is shown in the full screen, even if that means it's partially hidden behind a notch. That will prevent white bands on the sides in landscape mode, but you will have to make sure that you prevent content from ending up behind the notch.

You can do that with CSS env variables:

body {
  padding-top: env(safe-area-inset-top);
  padding-right: env(safe-area-inset-right);
  padding-bottom: env(safe-area-inset-bottom);
  padding-left: env(safe-area-inset-left);
}

Because you don't know if the user has the phone oriented with the notch on the left and right, you can use these env variables to add enough padding or margin to elements to prevent them from going behind the notch or other device parts.

Keep in mind that these env variables are the precise width of the notch, so if you just use the env variable, your content will sit flush to the edge. You'll need to add some padding or margin to make sure your content doesn't sit flush to the edge using calc:

main {
  padding-right: calc(env(safe-area-inset-right) + 1rem);
  padding-left: calc(env(safe-area-inset-left) + 1rem);
}

Rule #2: Mobile first

You develop websites on a large laptop or desktop screen, and usually your client is most interested in the desktop design of a website, so it might feel natural to just start with the design for the desktop site and then work your way down. But starting mobile first is actually easier and will result in less code.

If you build mobile first, you're building up your CSS in complexity. What I mean with that is that your mobile views are usually much simpler and thus require less CSS. They almost always have just a single column, and lack many of the additional flourishes you have space for on larger screens. If you build mobile-first, this means that, as you add styling for larger and larger media queries, you're adding to the design.

Start here

If you start desktop first, you already have all this styling that you then need to write more CSS for just to undo your more advanced desktop styling. So you're writing more CSS and if you're not carefully undoing all CSS, you end up with things like horizontal overflowing or text not fitting.

With mobile first, you save a large chunk of CSS you simply don't have to write, making it smaller and your website faster.

Rule #3: Design from content out

To determine where your breakpoint will be, you can opt to use values like 320px, 375px, 768px and 1024px, which all map to various real device widths. Basically, design for specific devices. But when new devices become more popular (#375IsTheNew320) your design might not look so good on those devices.

Stephen Hay, who wrote the book on responsive design workflows, advices you to start with your small screen, then:

"expand until it looks like shit. Time for a breakpoint!"

This focus on the content will force you to think of websites as inherently fluid. You can't design only your pixel perfect widths, because they don't exist.

Quick rule of thumb: you want your line lengths to be around 70 characters long. That translates (depending on the font!) to about 36 to 40 em.

Rule #4: Use ems in your media queries

With specific device widths no longer mattering, you should also switch out those breakpoint widths in pixels, to widths in ems. Your media queries are based on the content so this will let your site look great even for people that have made their browsers base font-size larger or smaller or have zoomed in their browser.

@media (min-width: 704px) { ... }

@media (min-width: 44em) { ... }

The rest of your design will properly adjust to this and make your site more robust.

Why not rems? At the level of media queries, rems and ems are the same so it doesn't matter which one you use, except em is shorter and rems have rendering issues in Safari.

Read more about using ems in our complete guide to CSS media queries

Rule #5: Min-width or max-width, pick one

Responsive design makes for an incredibly complex system. When your media queries use both min-width and max-width, or even combinations of them, you're massively increasing that complexity and reasoning about it becomes even harder.

min-widthmax-width
@media (min-width: 30rem) { ... }@media (max-width: 52rem) { ... }
@media (min-width: 44rem) { ... }@media (max-width: 44rem) { ... }
@media (min-width: 52rem) { ... }@media (max-width: 30rem) { ... }

If all your media queries work "up" or "down", you always know where to look when your site doesn't look as you expect it to at a certain size. CSS in new media queries you write will then never influence your earlier sizes. Just find out from which media query down (or up) you need to update your CSS.

Rule #6: Avoid fixed dimensions

It can be very tempting to use fixed dimensions for elements. After all, your favorite hand-off tool probably lets you copy them with ease. Elements with fixed widths (or margins) could easily break your layout if you're not careful.

Try to style element sizes in relation to their surroundings. Use percentages or viewport units. Prevent setting width and height and try to use their min- and max- counterparts. And if you do end up with a width breaking something somewhere, a max-width:100% can work wonders.

Rule #7: Use modern layout techniques

To expand on the previous rule, modern layout methods like Flexbox, CSS Grid and container queries are built to be inherently flexible and size according to their surroundings. If you make use of these layout methods, you'll end up needing much less media queries to achieve the same design.

Less media queries means less to reason about, and your code is shorter to boot.

A great way to (re-)learn how to build common layouts with Flexbox and CSS Grid is Every-layout.dev. It lists common layouts and explains how to build them using modern techniques.

Rule #8: Leave room for text rendering differences

It's tempting to create breakpoints right at the place where an unfavorable line-break occurs. To get that "pixel perfect". Of course we know the web isn't pixel perfect, and it never was.

If your breakpoints are too close to readable line breaks, then it might work in your browser, but different browsers and different operating systems have different ways of rendering text, which means that the line of text might be a couple of pixel wider or smaller,, and your design could break.

Instead, try to be a little bit loose with your media queries, leave a little space for things to be off by a few pixels before big changes in your design.

Rule #9: Decide in the browser

To follow these rules, it doesn't make sense to create all your breakpoints in a design tool. On the other hand, designing the entire site in a browser is difficult too. So what's the happy medium?

Create your designs in a design tool, with some rough responsive variants, but keep the choice of when to switch over to another design for when you're actually working in the browser. The Sketch artboard might be 750px wide, but if you're in the browser and the layout already makes more sense at 44em (that's 704 pixels), then use 44em in your css.

Rule #10: Give Polypane a try

With Polypane, creating sites and apps in a mobile-first, content-out way comes naturally:

  1. Start with a single pane and design your smallest screen.
  2. Add a new pane, and widen it until, to quote Stephen, it "looks like shit".
  3. Check the width of the pane and use that em value as your new breakpoint.
  4. Style it and repeat.

Start using Polypane for free with a 14 day trial.

Build your next project with Polypane

  • Use all features on all plans
  • On Mac, Window and Linux
  • 14-day free trial – no credit card needed
Try for free
Polypane screenshot