You have probably heard by this point that rems are the most desirable CSS unit to make layouts in. If you’re anything like me, you’ve probably taken this advice to heart - believing in the necessity of an accessible web, and all - and spent many a project with your calculator app open on your phone trying to convert all designer-supplied measurements into multiples of 16. If you’re anything else like me, it’s probably been a while since you looked up why you’re putting yourself through the conversion process.
You’re also probably wrong about it.
In a nutshell, the reason to use ems + rems is to support scalable interfaces. However, this conventional wisdom is vastly oversimplified, and misunderstanding it may make the use of relative units in CSS entirely self-defeating. To better understand, let’s take a look at our options for scaling interfaces.
Zooming
There are two different mechanisms for users to scale their UI. The first is the one you’re probably more familiar with - zooming. It is supported back to IE7, and therefore widely available in modern browsers. It is the default behaviour of the “zoom” finger motion on mobile browsers as well (something you should, by the way, never disable). It is usually a highly discoverable feature, and you may have used it before to test the scalability of your application.
If you’re already in the habit of using rems, you might not realize that they have nothing to do with how well your interface scales while zoomed.
Browser zooming works by scaling the size of your interface according to the factor of the zoom. To understand how it works, it’s important to understand that the CSS px unit is not a “true” pixel. This is a good thing, as it allows the size of a “pixel” to be standardized across many different devices with different pixel densities and still display in a predictable way. When the browser magnification is active, the browser is scaling the size of the CSS reference pixel, and therefore the size of the interface.
The key takeaway: browser zooming works with any CSS measurement unit, pixels included.
Font Size Scaling
This is the slightly older method of scaling UIs. Before zooming was ubiquitous in browsers, the user’s key mechanism for controlling the size of the interface was to scale up (or down!) the font size using browser or system settings.
This is the only accessibility feature that using rems and ems facilitates.
Rems/ems support a user’s browser font settings by referencing the font size at the root of the document to determine the sizes the fonts should be throughout the page. For example, the default browser setting of 16px will render a 2rem header at 32px. If the user were to scale up their interface to a default of 20px, everything sized with a 2rem unit would now render as 40px.
However, this type of interface scaling is dependent on two implementation details. First, only interface elements sized in rems/ems will scale up accordingly, as previously mentioned. Secondly, they will only scale when the html font size has not been explicitly declared, as the html font size will overwrite the user’s preferences.
In other words, if you’ve been setting your html font size to 16px (or 10 for ease of calculation) and using rems throughout, you may as well have been using pixels.
Changing Your Approach To Sizing
Our goal in using relative CSS units is to build more flexible, accessible, user-controlled interfaces. This remains a noble goal, but given the above facts, we must adjust our approach and use CSS units where they’re appropriate, rather than as magic bullet buckshot.
Firstly, it is still important to honor a user’s browser and system settings. To do so, we should continue to use relative units for font sizing and spacing, and ensure that we aren’t manually setting a font size on the html element. We should make sure that we test using text scaling settings, NOT browser zoom, and communicate with design stakeholders about the results.
Secondly, we shouldn’t force ourselves to suffer through dogmatic adherence to rem measurements everywhere else in our layout. For box padding/margins, media queries, and fixed-layout items, using pixels will be just fine.
Relative units are a useful tool in your CSS toolkit, but they will be more effective when used as a scalpel than as a sledgehammer. By using relative units exclusively with elements that require relative sizing, we can build more predictable, robust interfaces - and bust a few myths, while we’re at it.