704Days

704 days since this post was last revised. Specific details are likely out of date.

For the last few years I have been obsessed with avoiding pixels when specifying length units in my CSS. Now it’s time to about turn.
I’m sorry pixels. Can we be friends again?

Pixels: the good, the bad and the ugly

Pixels have always been the faithful servant of designers. A pixel represents something finite, controllable, reliable. These values make it uniquely suitable for communicating lengths in documentation and providing unequivocal feedback to developers, “That padding needs to be 11px, it’s 10px at the minute”.

It is self-evident that using pixels for length measurement in CSS solves a set of problems. Most obviously, when a design change or amendment need making to the code you can write the new value straight in.

However, for some time, from a technical point of view (particularly in a responsive web design world) pixels have presented fundamental issues. I won’t document those issues again here, as the original documenters have done a far better job than I would describing ‘why’ that was a problem in the past:

Inclusive and accessible approaches

Therefore, in more recent years, where appropriate, many CSS authors (myself included) have been specifying lengths as em/rem (when percentage didn’t make more sense). And it wasn’t just to make myself feel good and wholesome.

Despite the initial frustration and habit of converting a visual specified in px to rem or em, I’ve learnt to embrace new found abilities these units presented. Principally that em and rem provide some proportional flexibility as you build. Depending upon what you are building, it is an approach that has great merit. Let’s me exemplify.

As I write this, I’m prototyping new designs for this site. I’m no designer and so the ability to easily tweak the layouts and typography easily and proportionally is invaluable. If I set font sizes for elements in rem (equal to the computed value of ‘font size’ on the root element), when I adjust my root element font-size, everything set in rem increases universally in relation to that root size:

html {
    font-size: 1em;
}

.thing {
    font-size: 1.2rem; /* will be 1.2 x the value set in html */
}

Rem is supported in IE9 too so that browser gets resizable text, something that can’t be done in IE9 using pixels (they can zoom everything though). Mr Snook was talking about this stuff way back in 2011 so give that a read if this problem and the benefits of a rem approach doesn’t seem worthwhile.

So, yes, rems are really useful.

Em anyone?

I also really like ems for building some things too, as em values compound. And that can be a good thing when you understand what compounding can do for you.

When building UI ‘widgets’ (as opposed to the easy stuff like flowing text/web content) you can combine the way different length units are applied to solve specific problems. Read how that fine fellow, Simurai, used different length units to create a system for easily proportionally scaling an entire piece of UI. Genius: http://simurai.com/blog/2013/07/03/sizing-components/.

Later Chris Coyier, in a similar vein, explored the possibility of combining units to provide both sweeping and detailed changes as and when needed.

I’ve played about with both of those approaches in different scenarios and depending on your needs, I think they are both sound and useful approaches. Especially if you’re experimenting and want a way to try things out cheaply in the browser.

Understanding Ems and compounding

An em always looks to its parent and compounds. Imagine the body tag of a page is set to 62.5% font size (effectively 10px). Inside is an h1 that is set to 1.8em, so 10 * 1.8 = 18px.

Now imagine we add a span inside that h1. If we set the span (that sits inside the h1) to have a font-size of 1.6em, it is based on its context (container) so we get 1.8 * 1.6 which gives us 2.88/29px.

This may or may not be what you wanted. But it is very useful.

To solve the ‘issue’ you need to use Mr Marcotte’s ‘target / context = result’ formula. In this instance 1.6/1.8 = .888888889. So to get a 16px height, we set font-size to .888888889em (set on ‘.fixed’). You could probably ditch a few of the numbers after the dot but I’m leaving them there for completeness.

If you want an illustration of this to play with, I made a little Codepen to illustrate.

Back to authoring in pixels

Time has moved on. The prior problems with resizing text and media queries in modern browsers/devices are pretty much gone.
Depending upon your browser support matrix, you may no longer need to concern yourself with those issues. 

I feel like nowadays, when choosing the units to specify for lengths, it’s just down to authoring preference, team communication and weighing up the pros and cons that fixed (px) or proportional (em/rem) length units offer.

I still think there is great utility in using em/rem when prototyping creating visual components that need to scale or laying out a text based web page. In those scenarios, and especially when you want to respect things like user preference (from a browser text size point of view), it’s worth the constant px to rem conversions, even if you need to do rem to px fallbacks for older browsers (thanks PostCSS / Rob Wierzbowski: https://github.com/robwierzbowski/node-pixrem). Being able to set proportions and then tweak the overall size of content with a single value is incredibly useful as you feel out a design.

However, if you’re working with a full fidelity design, especially when that design pertains to something ‘web appy’, and you just want to express that design in code. For most situations, I’d say ‘just use pixels’.

My experience of late is that I’ve been building in a lot of ‘just in case’ that isn’t worth the hassle. If I ever do actually need to change that thing I can just do it. The reality is there will be less time spent doing that than building for a whole load of unlikely what ifs. For example, you can continue to change the roots size of text, even after the initial site is built and shipped but how often do you need to do that, really?

Plus if you’re using variables to provide consistent sizing it’s pretty easy to alter sizes throughout an entire design whether px, rem, or otherwise.

So I’ve been asking myself the question: when working from a visual composite, is the pay off of being able to change the root size if needed, worth the difficulties of constantly converting values?

I don’t care who you are. Unless you’re a weirdo, it’s easier to visualise a length related to you in pixels than it is to visualise that same length in rem or em. It’s also nice to be able to mentally grab a value you see in Sketch/Photoshop/Fireworks and use that directly in code with no mental conversion needed (who am I kidding, I NEVER do it in my head, Alfred has my back).

Conclusion

Perhaps ultimately, ‘just use pixels’ is the wrong thing to take away. It’s merely important to understand what each choice will buy you and cost you and make a choice accordingly.

If the hard work of figuring out a design has been done by a skilled craftsperson, I’m finding greater utility in authoring lengths in pixel units inside style sheets, especially things like margin and padding, background-positions and heights.

Values defined in pixels make maintenance of code more straightforward. It also makes code more portable as styles can be dropped in to another project without potential sizing compounding issues (em) or needing to adjust values due to different root font sizes (rem).

However, most importantly, pixels make working with designers day to day easier. Pixels provide a shared language between the worlds of developer and designer. This shared language makes it easy and accessible for anyone to jump in and change/tweak values in developer tools and get predictable results.
At the end of the day, we all just want to get great stuff made. Anything that reduces the friction in making that possible should be embraced.

Minor update

Since posting, @Nyalab on Twitter has since pointed out that there is a setting in browsers (Chrome in this case) that allows users to adjust text-size independently of page zoom. It’s quite a buried setting (you need to open the advanced section) but if a user sets a preference there (Extra Large for example) it won’t have any effect on text content specified with pixels (Medium was the example website given as it’s set with px).

I don’t know how many people use this setting, and likely nobody else does either (and I certainly don’t know how important that is to YOUR project) but to make text content as accessible as possible, you should probably still set it in rem or em.

On the other hand, if you’re building UI components. I maintain there is little benefit now in using rem/em.