Our job is not to control what every user gets but to give the interface the ability to perform the calculations it needs to provide enough flexibility.
Solidified image vs user-relative instructions #
Technically and ideally, an interface is a set of instructions that should work with whatever technology the user prefers or requires. We can use different approaches, techniques and units to achieve this, some more suitable than others.
px is among the less suitable units for interfaces. Pixels fixate sizes; layout, spacing and typography become more like they are in images, print and video. Each part grows equally upon zoom. It doesn’t go well with our goal of making the instructions as relative as possible to users’ preferences and means of interaction.
Any unit can be unsuitable in the wrong place. Still, it’s reasonable to see defaulting to px use in connection with a view on interfaces as something that requires micro-managing and self-centred coherency. Although, one isn’t proof of the other. When we approach the interface as something relative to the user instead, we see that variations, differences and inconsequence are all in its nature. We see that coherency is something to achieve across the web and not so much within self-invented arbitrary visual programs.
We also see that it’s not about only using one type of unit or never using another; we should use whatever unit and technique enable us to meet the users’ expectations, conventions and technical milieu.
Scaling isn’t zooming #
Modern browsers offer zoom through ctrl + + or -, or non-Windows OS equivalents; why still bother with relative units?
User-relative units give users better control than zooming does. They provide scaling and work not only on a site-by-site basis. Although, to be fair, some browsers also have a global zoom setting. With scale, the user controls the interface scale through an OS or browser setting if we have used the correct approach and units.
In a combination of fixed and relative units, scaling will only change the relative ones, while zoom will affect everything. This means we can specify the things that should scale and the things that shouldn’t. But it’s also a bit more complicated; we have to handle fixed, user-relative and viewport units.
Unit system #
Setting only the font size in relative units is not enough, but it’s perhaps a starting point. We need to have a system and know how different units work independently and together so we can use them where they are most effective – even px.
We don’t need a complex system as long as we know how different units affect each other. If not, the elements might crash and overlap each other. It can be helpful to do some manual tests, at least initially.
Uncritically mixing #
Relative units work beautifully with both scale and zoom. If we mix them uncritically with px, our interface can become a monster. I have previously made a Codepen demonstrating the effects of mixing rem and px.

The mess we can get when mixing rem and px sizes and the user has scaling set to 150 %.
px unit
#
The px unit can be helpful when we want the fixation it provides, not because we wish certain pieces to remain forever as we envision them, but because some things are better off not changing.
A reasonable use case is where a relative margin or padding would have distorted the content significantly. I wouldn’t bother with pixels for just a couple of rem or em, but let’s say we have 4 rem of margin and gutter in a grid. That’s already 64 pixels each. If the user has the font size set to 200 per cent, it’s 128 pixels. It’s unnecessary, and it only squishes the content, which is also at 200 per cent, into a smaller space.
A reasonable use case is where a relative margin or padding would have distorted the content significantly. I wouldn’t bother with pixels for just a couple of rem or em, but let’s say we have 4 rem of margin and gutter in a grid. That’s already 64 pixels each. If the user has the font size set to 200 per cent, it’s 128 pixels. It’s unnecessary, and it only squishes the content, which is also at 200 per cent, into a smaller space.
Pixels can create problems when scaling down because the spacing remains while everything else shrinks; some of the effects we wanted to avoid when scaling up appear when scaling down, such as content wrapping and unreasonably large spacing. The best way to figure out what works is to test the entire layout. I have made a Codepen demonstrating possible unit combinations.
Other than that, I think pixels are relevant for small things that don’t have to or shouldn’t scale, like borders and some box-shadows. Maybe that’s a general pixel approach, to use it for tiny things or the occasional sizeable vertical spacing.

Possibly reasonable ways to mix px with other units.
rem and em units #
I use rem for almost all sizing. I use em for the occasional media query, certain nested elements or when some measurements benefit from being relative to another size. Like in a table where the font size is set to 1 rem above a given viewport width and 0.9 rem below. In such cases, I find it helpful to set padding using em. It scales with the font size, and I don’t have to add more code to the media queries.
If I have buttons of different sizes, it can also be useful to define a base button size with padding in em, and build on top of that. That is if I want the padding to change according to the content font size. This is where a px unit could be used, but unless the padding is above 2 rem and you have a lot of elements, I don’t think it’s much of an issue.
ch unit #
For paragraph width, I use ch increasingly often. That is relative to font size, which should be relative to the user’s settings.
Viewport units #
I also use viewport units such as vmin, vmax, vw and vh. While these are relative to the users’ technology, they are not relative to their settings. I mostly use them for outer horizontal spacing and vertical sizing. I also combine them with calc() and rem for responsive typography.
Percentage unit #
On some rare occasions, I use percentage, but that’s almost always with a value of 100 to stop overflow. I don’t tend to set elements to full width or fill the screen more than what the content does.