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 em
or 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 em
guy).
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 rem
over 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.
Edit
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
em
or 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 ::before
or ::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 clamp()
with vw
. I personally don't have many designs that need this, however.
- For margin/padding of text, use
em
or 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 em
or rem
.
- 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
rem
.
- For border radius, percentages are okay, although
em
and rem
might work, too. Just test and see if they scale how you expect.
- For media queries use
em
, rem
or 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.
Edit 2
I just wanted to chime in on another thing that is top of mind right now, container
queries! I'm not going to dive into them, nor give my opinion even, but some people out there think that it might be possible to either completely, or almost completely remove media queries in favor of these. Whether that happens or not will remain to be seen, but I can guarantee you that some people will absolutely try to do that and enforce it as a rule. I can also guarantee that a whole generation of people that were trained on media queries will still be using them for many years to come.
Your question wasn't about media queries, I know, but I'm calling this out because this is related to consensus or the best way to do things, and I have no doubt that just as there's discrepancy between which is "correct", 768px vs 48em, the media vs container will be coming up eventually.
border-radius
specifically, often times designers want theborder-radius
to stay the same size regardless of the dimensions of the element. Or at least stay the same given a slight range then a different value for a different range.