I see different approaches to breakpoints and responsive design. Most of the time they are over-complicated and only making things worse. So here’s mine suggestion for device breakpoints that are in touch with reality.
And if my day keeps goin’ this way I just might… break somethin’ tonight
Responsive design
Let’s recap how to we design for different devices. You define some breakpoints -
conditions where your site changes. Then you describe what changes once
conditions are met. Conditions can be pretty broad, like for example @media print
that allows you to apply additional styling for printing pages. Or min-width: 1000px
that allows you to target only bigger screens.
Sounds easy, right? However the problem with CSS is that it give one too much flexibility without enforcing any structure. That causes CSS bloat and leads to unmaintainable stylesheets down the line.
Strict CSS
A saner approach is to let some constraints in.
- Add
<meta content="width=device-width, initial-scale=1" name="viewport" />
to your HTML - Define breakpoints for your website and stick to them
- Use only
min-width
so you are going from smaller to bigger screens
That is pretty much it. There are some tricky parts, though.
Use 1:1 viewport, this is important if you don’t want to pulling your hair out later. This way you will always work with something you’re looking at, not a scaled version of your website.
I guess everybody is using SASS or PostCSS or something that allows you do define CSS variables, so I won’t be stopping on defining variables and go straight to the next point. Just don’t go overboard, you ain’t going to need it.
CSS allows you to use min-width
, max-width
or both, plus some additional modifiers
like orientation: portrait
and god knows what else. However there are good parts and
there are bad parts. Some things you don’t have to use if you don’t want to
spend the rest of your live debugging the cascade.
All your styles should look like this:
// Hides element on screens bigger than $small breakpoint
.sm-hide {
@media (min-width: $small) {
display: none;
}
}
Devices
But we can’t use only min-width
! We want out site to look best on mobile devices
We have to use orientation: portrait
and landscape
! Maybe not. Think what
is exactly you are trying to achieve?
Let’s ask our project manager for some specs. Some realistically formulated requirements could be:
- Page should take up full width on a smaller screen
- Display sidebar on a larger screen, collapse it on a smaller screen
Now we’re talking. Note that it doesn’t mention landscape or portrait. Just introducing a general idea of smaller and larger screens.
Let’s take a look at some common internet-consuming devices. And see where we can draw a line between smaller and larger. Don’t worry if looks a bit Apple-biased, the results are universally applicable.
CSS Width | |||
---|---|---|---|
iPhone Portrait | 320px | 20rem | |
iPhone 6 Portrait | 375px | 23.4375rem | |
iPhone 6+ Portrait | 414px | 25.875rem | |
iPhone Landscape | 568px | 35.5rem | |
iPhone 6 Landscape | 667px | 41.6875rem | |
iPhone 6+ Landscape | 736px | 46rem | |
iPad Portrait | 768px | 48rem | |
iPad Landscape | 1024px | 64rem | |
iPad Pro Portrait | 1024px | 64rem | |
Macbook Pro 13” | 1280px | 80rem | |
iPad Pro Landscape | 1366px | 85.375rem | |
PC Notebook | 1366px | 85.375rem |
Middle ground
When people think about breakpoints they often imagining them as some magical bullet that can detect if you are using an iPad.
I am referring only to @media (min-width: $variable)
well-behaved
breakpoints as this are the only ones you should use.
Think of a breakpoint as a fence. Like a fence it has two sides, everything that is smaller than the specified width and everything that is equal or larger than the specified width.
In other words you can think of it as a equals or larger than equation:
.menu { folded }
@media (screen width >= x) {
.menu { unfolded }
}
That makes me think that in most cases you could do with a single breakpoint.
Or at the very least we can start with it. Let’s call it $medium
. Everything
on the left will be considered a smaller screen and everything on the right
is a larger screen.
Why not name them $desktop
/$tablet
/$mobile
/$whatever
? Isn’t this
semantic? I hear this question a lot. The reasoning usually is that it’s hard
to remember what is $middle
or $large
. First of all the semantics here is
meaningless. One can rotate an iPad, they can release a new device tomorrow,
and you will have to rename all your classes and whatnot. Besides, each
breakpoint is only a fence.
So I propose to claim a line between vertical and horizontal iPad orientation
as a $medium
breakpoint. A perfect place to start moving further. By default
and until we are being viewed from the devices that is larger than $medium
,
and that includes: mobile phones, tablets in portrait, half of the screen – we
display content, say, in a single column.
Once our media query is triggered, for everything that is bigger than
$medium
: that is for example an iPad in horizontal mode, computer screens,
TV – we display multiple columns or un-collapse the menu.
Other breakpoints
Let’s separate the devices on a smaller side of the $medium
so we can target
portrait and landscape modes separately. This way when somebody is looking at
your website on his phone he sees the initial styling.
Once he rotates the phone - he makes a first jump over the $small
breakpoint
fence. Everything that is styled with min-width: $small
kicks in.
This is what one would see the on an iPad in portrait orientation. But our
users want to see more. So they rotate the iPad (or get an iPad pro) and that
moves them over the $medium
breakpoint.
The last one, $large
covers everything bigger than an iPad in Landscape. That
is the computer screen and the iPad Pro.
Final results
Pixel sizes are provided only for reference. You should stick to rem-based
sizes. Calculations are based on the default 16px body font size. I don’t
recommend using pixels. Stick to rem as this is not relative and equals body
font size. With rem
you can increase font size when needed and the layout
will adapt. For example, if you need to show something on an HD TV across the
room.
$small | $medium | $large | ||||
---|---|---|---|---|---|---|
Phones Portrait | 35rem | Phones Landscape | 55rem | iPad Landscape | 65rem | iPad Pro Landscape |
560px | iPad Portrait | 880px | iPad Pro Portrait | 1040px | Notebook / Desktop |
I have chosen these after some consideration, but nothing is written in stone, you can change them as you see fit for your project. Them menu might be not fitting in only this much or something breaks.
Anyway here are the breakpoints in SCSS format, I tried to round them up a little bit:
// $small $medium $large
// Portrait | Landscape Portrait | Landscape Portrait | Landscape
// Phone | Phone iPad | iPad iPad Pro | iPad Pro
$small: 35rem; // 560px
$medium: 55rem; // 880px
$large: 65rem; // 1040px
I believe this approach will bring more good than those obscure pixel-based breakpoints found in CSS Frameworks everywhere. Start small, use an Immutable CSS library and have fun.