Last week I refreshed my website to take advantage of new baseline 2024 stuff (and one old thing). Another change I made was a move from rem
to px
units.
I pondered this change back in August. The idea being: keep rem
for font size and use px
elsewhere. This is a big change for me. I’ve dogmatically used only relative units in rem
and previously em
for years.
In Practice
It’s easier to show the end result than to describe it. For most users there is no difference. In the screenshots below I’ll show my website before and after. My old CSS used rem
units everywhere. My new CSS uses rem
only for font sizes and queries.
100% zoom
At the default zoom level the before and after screenshots are almost identical. There is a minor difference in the sidebar due to unrelated changes.
150% zoom
Zooming in to 150% and beyond also reveals no material differences. At this scale my responsive design changes to a two column layout.
🔎 Browser zoom doesn’t care what units are used.
24px base font size
In Chrome and Firefox search “font size” on the settings page. This is an accessibility preference more permanent than zoom and has a slightly different effect.
Increasing the base font size 150% — from 16px to 24px — does reveal a difference.
🔎 Notice how my new CSS allows more content to fit in the initial viewport. This is because only rem
font sizes scale up. Spacing defined in px
units remains the same.
🔎 The old CSS remains identical to the 150% zoom example.
32px base font size
The WCAG “Resize Text” guideline suggests:
Except for captions and images of text, text can be resized without assistive technology up to 200 percent without loss of content or functionality.
So let’s double the base font size to 32px.
🔎 At this scale my website adapts to a single column layout. Again, fixed vertical spacing in px
units allows more content to be visible.
Pixel queries?
In the screenshots above I’m still using rem
units for all @media and @container queries. Below I test only my new CSS using px
units for all queries too.
I don’t like this effect and chose not to implement it.
🔎 The responsive layout no longer adapts to font size at all. The result is increasing squashed text as the base font size increases.
Insights
Before I discuss opinionated design let’s recap the more objective lessons:
- Browser zoom will zoom the same regardless of units
- Relative units make zoom and base font size scale the same
- Relative units allow uniform scaling with the base font size
- Mixed units allow selective scaling with the base font size
- Fixed units for font size break the accessibility setting
I haven’t demonstrated that last point because you should already know it. Setting font sizes in non-relative units like px
is needlessly harmful.
Opinions
Professional design usually adheres to a restricted set of sizes that follow an harmonious scale. This provides logic and reason to both the design and code. By using relative units everywhere — font sizes, spacing, and responsive queries — that scale remains uniform, regardless of zoom or base font size.
By mixing relative and non-relative units it’s still possible to have such a scale. At least at the default base font size. If the base font size increases you trade some harmony for practicality; more content remains visible. Albeit a little tighter.
For my website I’ve made the change from rem
everywhere to:
rem
units for font sizesrem
units for container queriespx
units elsewhere for borders, margins, padding, etc
The end result will look the same for most visitors. Only those that have specifically changes the default base font size will see any difference. Personally, I think the trade-off is worth it. It also makes development a tad easier because px
values are easier to visualise than floating rem
values.
What do you think? Let me know on Mastodon or email.
There is one negative side effect:
12px base font size
So far I’ve only discussed increasing size. What if the base font size decreases?
My old CSS effectively zooms out; everything remains uniform. My new CSS decreases font size while spacing remains larger. This results in content spread out with less content visible. This is the worst of both worlds!
I wonder, how many people browse the web with a base font size lower than the default 16px? This is not an immediate concern for me but worth noting.
I could fix this with a min
function:
h1 {
margin-block: min(2.25rem, 36px);
}
This would allow the margin to scale down proportionally. Therefore a base font size below 16px behaves like zoom, whereas increased sizes selectively scale.
Seems like a lot of work!