Ludwig Wendzich

All units are made equal, sort of

Over the past 10 years (I can’t believe it’s been that long either) I have read many articles claiming to have discovered the CSS unit to rule them all. The problem was, none of them did. They all sucked, in their own ways. As much as they were good at some things, they were poor in others.

##Roads past travelled

###px The first unit I’d ever encountered in web development was the humble px. It was very simple to understand (especially in a world where 1px literally meant one pixel.) Living in the world of px was very easy. We assumed that everyone used monitors that were 800x600 in size, later 1024x768 and so one. We had pixel-perfect control of our websites; we ruled the www with an iron fist — our way, or you don’t get to enter.

The drawbacks to the humble px are clear today. Defining font-size in px is a bad idea; nowadays we care a little more for the consumers of our product and thus if they need bigger text we’d like them to be able to request their browser to make all the text a little bit bigger for them.

We also discovered that some people didn’t actually upgrade to 1024x768 computers, others had upgraded further to 1280x800 computers and then there actually existed a group of people who didn’t use their computer with all programs maximised all the time. px weren’t flexible enough for us it seemed.

###%

For a while we stuck with px as our unit of choice for font-size but experimented with using % for layout. width: 30% for the sidebar, width: 68% for the main content container. This worked great, sort of.

High resolutions viewed stretched websites. Low resolutions viewed squished websites. % was not the unit to rule them all.

###em

I first heard about the em when Richard Rutter wrote about them. It was connected to this idea of line-length and how text is easier for us to read when we limit the number of characters that span a line (it’s easier for us to find the start of the following line without losing our place.)

px and % units were out. ems were in. But the problems of using the em unit were soon very clear.

Layout-wise the em was a glorified, scalable pixel. It suffered all the same failings of a px based website; while at the same time making it impossible to understand what was actually going on in one’s CSS.

ems were far too relative. It was impossible to tell that font-size: 1.333333em; and font-size: 2.18888888em; were in fact going to render at the same size. We had no way to reset the context of an element. Context inception occurred.

It was not right.

##A new road

The increased support of @media queries, specifically of min-width and max-width, as well as the maturing of other parts of the CSS spec, specifically min-/max- height/width, has made it possible for us to combine all these units in one conversation. Allowing use to use the best of each unit and not deal with their shortcomings.

###rem

The final piece of the puzzle of course is the rem unit. Think of it as an em unit that is scoped to the html element’s context.

html { font-size: 10px; }
p {	font-size: 1.2rem; //12px }
	
html { font-size: 12px; }
p { font-size: 1.2rem; //14.4px }

I didn’t quite understand why this would be useful when I first read about this unit. To me, it was like a new pxmasquerading as an em which we all knew was better; despite being a pain in the ass to use.

The magic, however, is that, that definition is completely correct, and exactly why the unit is so awesome.

px is a great unit because you completely understand what it means. px is a unit scoped to the base unit of the resolution of your monitor (the super-context is the operating system). On HiDPI (Retina) displays this actually amounts to a 2x2 unit of actual pixels. But every element in your CSS file that references a px is referencing a unit of the exact same size. 12px is 12px is 12px. The reason why px suck though, is that we have no control of that base unit. A px is a px is whatever our operating system decides a px is.

With rem: a rem is a rem is whatever we decided a rem is in our html {} block. We got to define the super-context of our units. 1.2rem is always 1.2rem and when we increase the size of 1rem we increase the size of every 1.2rem definition in exactly the same way. rem units have a super-context of the html element, instead of the operating system.

(This is useful when we want to bump up the size of everything for large viewports.)

We have stylesheet that we can actually understand. We have control over the relative size of every unit in our stylesheet. Clients (browsers, and thus the consumers of our products) also have control over the relative size of every rem unit in our stylesheet. Assuming that you didn’t define it in px of course.

##The rules of the new road

I now use the following rules when writing CSS.

##Dealing with IE

There’s always this section, isn’t there. Unfortunately, IE exists and we must deal with it. IE 9 is the first version of IE that supports the rem element. Fortunately, assuming you set your super-context to html { font-size: 62.5%; } it is fairly simple to write backup CSS for IE-less-awesome.

* {
	font-size: 10px;
	font-size: 1rem;
	}

Whenever you define a new context, you define it in pixels. You won’t need to touch your objects (eg. .search-form{}) because they’re font-size is inherited or defined in ems. Sure, you may protest that you lose the ability to change the font-size of your super-context now, but that’s only possible with media query blocks and we know that the support for rem units and @media queries are almost identical. You can’t lose something you never had.