Halvor William Sanden

The unfriendly px unit

Exit px and bad coherency #

Pixels fixates the layout, the sizes, the spacing and the typography. It’s useful when we make things like drawings, ads or video. But when it comes to interfaces, we want as much fluidity and relativity as possible. Something pixels are unable to provide.

Technically and perhaps ideally speaking, an interface is a set of instructions that should work with whatever technology the user prefers or needs. That means we should aim to make the instructions as relative to preferences and means of interaction as possible. Pixels are not relative, they are only for fixating an envisioned picture. Part of this can be summed up as solidified and unified pixel perfection everywhere vs user-relative variations.

The former might sound like a good principle because of coherency connotations. But it’s bad coherency, the one where visual similarity comes first, and users are somewhere down the list.

The latter sounds less positive. Variations, differences and inconsequence are rarely seen as key principles for good interfaces. But they can be, as long as we are not giving the users an inconsequent experience across the web. And I’m not talking about visual branding, which has a tendency to be the bad kind of coherency. I’m talking about meeting the expectations of the users and making interfaces relative to their settings and means of interaction (among other things we will not get into here).

When we are using px, for instance in a font-size declaration, we get the same size everywhere. When we define it using a relative size, like rem, the users get the size relative to their OS or browser font size setting. We have no control over what each and every user gets, but if we build it right, we give the interface the ability to perform the calculations it needs in order to provide enough fluidity.

Scaling isn’t zooming #

Modern browsers let us zoom using ctrl + + or -, or non-Windows OS equivalents. Some browsers also have a global zoom setting. And this works pretty well. Why still bother with relative units? Because zoom isn’t scaling. With scale, we are forced to have more control over the units. And this is a good thing, not only relative to the user, but sizes relative to each other.

Relative units work beautifully with both scale and zoom, pixels don’t. If we mix the two, our interface becomes something of a monster. I have previously made a Codepen demonstrating the effects of mixing rem and px.

The mess that we can get when mixing rem and px and the user has scaling set to 150 %.

What I use #

Using relative units means we should use them everywhere. We don’t need a complex system as long as we are aware of how different units affect each other. If not, things might flow into or out of each other. It can be useful to do some manually test-driven development, at least in the beginning.

rem and em #

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 useful 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 just build on top of that. For instance using utility classes. That is if I want the padding to change according to the font size.

ch #

For paragraph width, I use ch increasingly often. That is relative to font-size, which again 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 the users’ settings. I mostly use them for horizontal spacing and vertical sizing. I also use them in combination with calc() and rem for responsive typography.

Percentage #

On some rare occasions I use percentage, but that’s almost always 100 % as a way of stopping overflow. I don’t tend to set elements to full width or fill the screen more than what the content does. If I have a selector with auto width, it doesn’t shrink with the viewport, so I tend to use a media query and change it to 100 % at a fitting point.

A few instances of px #

I think pixels are still somewhat relevant for things that are small and don’t have to scale. Borders and some box-shadows are the only things I can remember having used px for in years. I don’t see myself writing border-width: 0.0625rem anytime soon.