I am aware of responsive design, but that seems to me to be saying that there are X different screen sizes, then proceeding to use px on each of them, having the same scaling problems on X different screen sizes.
There is some truth in there. Some people, when doing responsive versions of a site (be it mobile-first or desktop-first), will have common breakpoints in
px from whatever they were trained on (768, 1024, etc.). I wouldn't say that this is right or wrong, it is just what some people are used to. Other people will tell you to use
rem for these. If you dive deep enough, however, most people tend to point to this article from 5+ years ago with a Safari bug as to why, and I haven't seen anyone post a more recent test (nor have I even tried, and I'm an
which are effectively fixed (with reference to their ratio to a given item), and only make sense with text (can they even be applied to other elements?).
You can absolutely use them with more than just text. For instance, if you have a button you might want the space in the inline direction (left and right in the traditional syntax) to be relative to the current font size, so something like
padding-inline: 2em might make sense for a specific design.
It seems intuitive to me that percentages are the only truly proportional way to define resize-proof sizes, but it can't be that simple, because every book, tutorial, Udemy curse that I look at seems to use px, or just about anything other than %.
I think the major problem with percentages is that the question always comes down to "percentage to what?". To the viewport? To the box? To the current font size? And if we are a percentage of something, is that something a percentage of something else. This is actually why you'll often see people using
em, just because the calculation is more straightforward and obvious, and doesn't change as you nest things. Also, percentages in the block direction (traditionally top and bottom) can be vague, or they at least not as understood.
So, please explain it to me like I am five. Why not use % or viewport related sizes on everything?
We used to do that, actually, at least with percentages. It was very common to do a
35%/65% two column layout, although in reality because of whitespace or padding/margin issues we'd cheat and do something like
33%/62% or something. Eventually some of us figured out the
font-size: 0 trick on the parent, or we'd do the
</div><!-- vertical whitespace -><div> trick, or possibly just force no whitespace such as
</div><div>, but it always felt hacky and it was very fragile, especially once we gave up control to CMSs.
So that's where grid and flexbox came in. We knew we wanted "percentage based layouts", but the rules for percentages were already set in stone and changing them would be a giant backwards compatibility break.
As to why not viewports, they suffer from the same problem as percentages, at least as far as "two things next to each other" where you have to hack to make it work. I do think that viewport units do shine, however, very specifically when used as a min or maximum size. For instance, for a font in a header you could
clamp it to a maximum of
5vw which allows you to scale, but only up to a certain point. Same with a box. At a minimum it should be 1/3 of the screen, but if there's room it can grow bigger. But they also suffer from the fact that
50vw on my mobile device if drastically different than my landscape desktop setup.
I think my summary would be:
The rules for percentages were set in stone a long time ago and can't be changed. We have a feeling for what we want them to do but it doesn't align with reality. Newer units were created to solve this, however. As to viewports, they have a time and place, but there are so many physical sizes available that you are solving everyone's problems by solving no one's problems.
Is there a general consensus of best practice? I.e some book, website, Udemy course which will tell me what too use which measurement unit (and why)?
All I can really tell you is what I do, which is based on 20+ years of experience, along with what I'm still learning as I watch other people build things, or inherit other peoples sites.
- For text, use
rem. They are both the same as long as you understand what they are relative to. Personally, I'm
rem for 99.999% of text with maybe a
em if I'm doing something funky in
::after. Also, I still set
font-size: 62.5% on the HTML tag although I don't know if that's still cool. If you want fluid text, which not every design calls for, consider using
vw. I personally don't have many designs that need this, however.
- For margin/padding of text, use
rem. Especially for paragraphs, you usually want the vertical distance between two text blocks to be essentially "a blank line" which you can get from
- For box alignment at a high level, use grid and/or flexbox. I'm personally a
grid guy and I use the
fr units all the time. If you aren't familiar with
fr, they are effectively what everyone wanted percentages to be. Flex is great, too. The when and why really depends on your skill but they honestly can swap in an out 75% of the time.
- For anything else related to boxes, use
- For border radius, percentages are okay, although
rem might work, too. Just test and see if they scale how you expect.
- For media queries use
px. I personally use
em across the board but like I mentioned above, I haven't re-tested that in years. Another developer on my team uses
px, however, and we get along just fine.
That's about it. You'll see I'm
rem heavy in my use, but that's just me. 90% of the other units don't interest me, or they are for weird edge cases. For instance,
ch can be used to limit line length by character count. If that works for your design, try it, but I still use
rem for that, too.
Lastly, one of the biggest hurdles to overcome is to just accept that not everything has to look perfect. Beyond the millions of screen sizes, users can change their zoom as well as their default font size. This is a user explicitly saying that they want something different. The information conveyed needs to be the same, but it can absolutely not look the same as designed. It should be consistent, and you will find edge cases (like line length when you always assumed a header would be a single line how it flows to more lines at certain zooms) and you can tweak as necessary.