How to choose between rem and em

A few days ago I found this article that argues for using rem units when defining font sizes. Generally speaking this is good advice. The rem comes with great predictable behavior, just like pixels do. But the rem also comes with accessibility advantages. When a user changes the font size in their browser settings, the rem and em unit will both respect that and resize accordingly while the pixel unit doesn't. That's great news for the user. But how do you choose between rem or em? Time to go in depth on what these units do. First I'll explain how each unit works and what they do. Based on that I'll explain how you can make the decision for a sizing unit.

The rem unit

Since the rem unit is the easiest one to understand and use, it will be the sizing unit I start off with. The rem is relatively new but if you don't have to support IE8 anymore you can safely use it. Rem is short for "root em", that's because it is a lot like the em unit except it is relative to the root font size.

So, what does this all mean? The rem unit is a sizing unit that's related to font size. With default browser settings 1 rem should be equal to 16px. That is because the default browser font size is, you may have guessed it, 16px. So using rems is almost as easy as using pixels. Want to make something 80px wide? That will be 5 rem please.

More complicated things like 100px will require you to do some math but if you use something like Sass I recommend that you check out Bourbon.io, it provides a rem-calc function to help you calculate rems.

A workaround many people use is to set the body's main font-size to 10px so 1 rem equals 10px on their website instead of 16px which will make working with rems a lot easier. The cool thing about the rem unit is the fact that 1 rem will always be the same size everywhere on the page, no matter what.

The em unit

The em unit is a lot like the rem unit. The difference between them is that the rem unit is always relative the the root font size. The em unit is relative to it's containing element. An h1 that is directly inside of the body and has a font size of 2 em will have a font size of 32px if we assume the default browser font size is in tact. If you would add a link inside of that h1 and you would want that to be 24px you first instinct would probably be to use 1.5 em as a font-size for that anchor tag. Let's try this out.

So... what went wrong here? The header has a 2 em font size, the anchor is 1.5 em so the anchor should be smaller that the rest of the text, right? Except, the anchor is larger than the rest of the header text which makes no sense. Remember that I stated earlier that the em unit is relative to it's containing element? That's why the anchor is larger than the header text. The anchor is a child of the header so a 1.5 em font-size means that the anchor's font size should be 1.5 times the size of the anchor text.

This is something that makes the em a complicated unit to work with, you can imagine that deep nesting with multiple font sizes can get really ugly at some point. A simple demonstration:

What you see here is a list with a nested list. The outer list has a larger font size than the inner list. This happened because I set a 0.8 em font size on the ul tag. So when there's a nested list, this 0.8 em is relative to the 0.8 em font size the outer list already has. So the outer list is 80% the font size of the body. The nested list is 80% the font size of the outer list. Confused? I understand, the em isn't a very straightforward unit.

Making the decision

Now that we know how both units work we should be able to make an informed decision. So, should we use rem or do we use em for our sizing? The answer, according to me, should be both. Whenever you want to have absolute control over a size you probably want to use rem. An example would be an element that you would normally make 100px wide. You want that element to have the same size, no matter where in the document you use it, the size has to be 100px. That is a case where you should convert that 100px to rems.

However, there are cases like the link inside of an header element where you might not want to set an absolute size. You might want to say this header element should have a font size that is two times larger than the body text that it's above. That would mean that you want to use a 2 em font size because then you know that your header is always two times larger than the body text of the element. Taking this one step further you might want to say that the anchor tag's font size should be 75% percent of the header's font size. That's 0.75 em.

What I would like to conclude here is that both of these sizing units are extremely powerful. One is very good for setting absolute sizes that are still accessible and adaptable. The other is good for setting relative sizes, whenever something should be x times the size of something else, regardless how big, the em unit is your friend. I do think, however that the rem units should be the unit of choice in many situations. But especially with margins, paddings and certain spacing situations I have found the em unit to be the best choice because all those sizes are usually relative to another size and that's where the em shines bright.

So, next time you're faced with the rem vs. em decision I hope you think about the way they each work and make an informed decision. My rule of thumb is: rem replaces absolute pixel sizes, em is for relative sizes. If you have questions for me, feedback or want to get in touch you can always contact me on Twitter.

Using Flexbox in the real world

The Flexbox module for css was built with the intent to make a more robust, less hacky way to layout elements on pages. When you're building a webpage you often don't know how high or wide every element could or should be. This can cause problems in certain layouts which lead to ugly hacks. Flexbox solves this widespread layout issue. The module has been in development for quite some time and the W3C gave the spec a "last call working draft" status back in september of 2014. The browser support for this module is very good if you don't have to support IE9 so you can safely use it. In this post I will provide a few code examples to show you how you can use Flexbox in some everyday situations.

Creating a filmstrip

Have you ever created a horizontally scrolling filmstrip kind of module? You know the size of the each element in the strip and the size of the containing element but the size of the inner element, the filmstrip itself is unknown. This would normally result in a layout like this and you would have to use Javascript or hardcode the size of the inner element to make this work.

So what would happen if you used Flexbox for this? Well, Flexbox allows an element to grow, not only on the y axis like an element normally does, but also on the x axis. It's one of the reasons Flexbox is really cool. Let's try this.

It's pretty neat, isn't it? Between the first and second example there's only three lines of code that are different. Okay, actually there's a little more but I'm not counting in the vendor prefixes because you don't have to write those if you use an autoprefixer. The first difference is that we give overflow-x: scroll; to the filmstrip container, that's just to make the contents scroll. The second step is to set display: flex; on the inner element. If you did only these two things, the items inside of the inner element will shrink to fit inside of their container. You don't want this so the last thing you do is add flex-shrink: 0; to the filmstip items. The shrink property has a value of 0(false) or 1(true). There's also a flex-grow  property, it's the same as the shrink property but it determines whether an element will grow or not.

Vertical centering

Ever since I started writing css this has been a problem. How do you center an element, with or without a known height, in a container that is or isn't flexible? No matter how you look at it, vertical centering is annoying. I've used hacks that would absolutely position the centered element at 50% from the top and then I would use a negative top margin to push the element towards the center. Another method is to use translating which is slightly cleaner but you still have to use position absolute and a top offset of 50%. You could display your stuff as if it's a table and then vertically center content which works well but it just doesn't feel right. It starts to feel plain wrong once you've tried to do this with Flexbox.

So in this example I've set up a container and inside of that container is an image. Flexbox is used to center the image both vertically and horizontally inside of it's containing element. The property that is used for vertical centering is align-items . The property that is centering horizontally in this example is justify-content . In my opinion, this is the best way to vertically align items I've seen.

Fitting things into a container

The filmstrip example gave this one away already but Flexbox can be used to fit an unknown number of items into a container. This is really nice if you have a couple of images but you can't really be sure of how many. You could optimize for a certain number, let's say four in the case of this example. And then for the edge cases where you have five images or more, you have Flexbox to make the images smaller so everything will still fit nicely into the containing element. Let's check it out.

All we had to do to achieve this is add display: flex; to the containing element. In the first example we saw that, by default, children of an element with display: flex; will shrink to fit inside of that container.

Conclusions and further resources

In this post I showed you three examples of what you can achieve with Flexbox and how you can do that. Note that we just used Flexbox for three small things and that I didn't mention Flexbox as a method of laying out your entire page. The reason for this is that Flexbox is not intended for that. There is a spec on the way for laying out your entire page and it's called grid.

If you're looking for a good overview of how Flexbox works I recommend that you visit this cheatsheet on css-tricks.com. This cheatsheet provides a lot of information on how you can use Flexbox and what properties it has. Lastly, if you're looking for more examples of what problems you can solve with Flexbox check out this "solved by Flexbox" page.

Filling in the blanks with calc()

One of the things in css3 that I don't see used very often is the calc() function. Even though this function might not be useful in every scenario it certainly has it's own use cases. In this post I'll try to outline a few of these use cases for you. First, let's start with a quick introduction to the calc() function.

What is calc()?

Calc()  is a function that was added to css3. It allows you to perform calculations on a certain property value, for example the width, font-size or even the margins of an element can be calc()-ed. The syntax for it is quite simple:

.my-class {
    width: calc(100% - 3em);
}

This code snippet sets the width of an element to 100% minus 3em. What's interesting about this is that we're combining both percentages and em values. So you can be partially fluid and partially fixed in your layout. Calc is very powerful and will perform this calculation whenever the element is being layed-out on the screen, making it incredibly flexible. An important thing to notice here is that there are spaces around the minus operator. These spaces are required.

Using calc for gutters

When building your layout you will often want to have a certain gutter in it. For instance, you could want a gutter that is exactly .75em all the time between two elements. For these cases calc is a perfect fit. Here's an example of that.

In the embedded codepen you'll see that we used only a small amount of css to accomplish this layout. A quick look at the css:

.item {
    height: 50px; 
    float: left; 
} 

.item-1 {
    width: 25%;
    background-color: #c0ff3e; 
} 

.item-2 { 
    width: calc(75% - .75em); 
    margin-left: .75em; 
    background-color: #0ff1ce;
}

The nice part about this is that a use can adjust their font-size and the layout will adapt to that because we've used ems. The calc()  function will make sure that our page will still look pretty. If you take this approach to the next level I'm pretty sure it should be possible to use calc()  in a very advanced and flexible grid system.

Calc to fill up the page

There are times where you might want to make an element take up all the width minus some known portion of the page. This becomes interesting in the case of a sidebar with a known width and content that should make up the rest of the page. Let's jump straight in with an example, shall we?

If we ignore all the kitten cuteness that Placekitten.com is providing this example with we're left with this piece of relevant css.

.item-1 {
    width: 250px;
}

.item-2 {
    width: calc(100% - 250px - .75em);
    margin-left: .75em;
}

What this demonstrates is that it suddenly becomes easy to have a partially fixed and partially flexible layout and that calc is very powerful because you can mix all kind of values. Pixels, ems, percentages, calc()  will calculate them for you. It's pretty cool actually.

How about browser support?

I'm glad you asked, browser support is more than decent for the calc feature. All new browsers have implemented it and they have done so for quite some time. Even IE has had support for some time, they only didn't implement multiplying and dividing until IE10. For an up to date list of support you can refer to caniuse.com.

Conclusion

In this post you've learned what the calc()  function is in css3 and I've showed you two real word examples of when you might want to use calc()  in your own projects. Browser support is good so there's nothing stopping you from sprinkling some calculations in to your css. If you have questions, suggestions or feedback you can always send me a Tweet.

Understanding HTML5 srcset

Every since responsive design became a thing people worried about the sizing of their images. Why would you serve an image that's 1800px wide to a device that is only 320px wide? That's a very sensible question to ask when you're dealing with responsive design. If you consider that this 320px wide device might very well be a mobile device that's using a 3g connection this question makes even more sense.

Working towards a solution

I think it was a few years back when I saw people debating the problem of responsive images. How would the syntax look? How will it be compatible with current browsers? HTML5 isn't supposed to break backward compatibility. I've seen a proposal for a element come by. That looked promising. But eventually something else come along and it’s called the srcset.

How it works

The srcset is an attribute that takes a list of images that a browser can choose from. By using the srcset you are trusting the browser to make smart decisions about what image is shown. If you want to have a crop out on small screens and then a different version on larger screens you might be in for trouble. Browsers are entirely free in their interpretations of the srcset attribute. They (should) try to be sensible, but Chrome 40 caches your images, so making the viewport smaller won't trigger a reload on the image. Why? Well, why would it. The browser assumes that a higher resolution version is 'better' and it won't waste an extra URLRequest on fetching your lesser quality image.

An example of using srcset:

<img src="http://placehold.it/100/100"
     srcset="
         http://placehold.it/320/320 320w,
         http://placehold.it/640/320 640w,
         http://placehold.it/960/320 960w">

The list we define uses this syntax:

<image_src> <image_width(in pixels)>

We could also define a pixel density:

<image_src> <pixel_density(2x, 3x etc.)>

But I want to have some control

Understandable, while this feature is somewhat of a block box, it isn't all black magic that goes on as Chris Coyier illustrates in his blogpost: You're just changing resolutions. The bottom line of what he illustrates is that a browser uses simple math to determine the best image for the current case. What the browser does is devide the image width by the viewport width and then checks how it matches the current pixel density.

Example from Chris' blog:

320/320 = 1
640/320 = 2
960/320 = 3

Imagine using a browser that has a 320px viewport. The images we are offering are 320, 640 and 960 wide. The browser does the math and decides that the 320w image is the best one since we are using a 1x pixel density device.

Now imagine using a retina device in this same case. The browser will now use the 640w image. Why? Well, a retina device has a 2x pixel density. So the 320 image is too small. It needs a bigger image.

More control please!

The browser always uses the full browser width to do the math now. But what if we needed to display images at 33% of the viewport on large screens, 50% on medium screens and 100% on small screens?

This is a question I really struggled with for a bit because here's where things get magical. But luckily we got a great mental model to work with because of Chris Coyier's examples. So, let's use the same html snippet we had before but we add the rules I just specified by using the sizes attribute.

<img src="http://placehold.it/100/100"
     srcset="
         http://placehold.it/320/320 320w,
         http://placehold.it/640/320 640w,
         http://placehold.it/960/320 960w"
     sizes="
         (min-width: 768px) 50vw 100vw,
         (min-width: 1200px) 33vw">

I've used some arbitrary values for the definition of what is small, medium and large. The first line should be explained, it says that we intend to display images at 50vw on a viewport that's 768px wide. If it's smaller we use 100vw. We don't need that "if it's smaller" part on the second size because we already defined a rule for that.

Okay, so now let's do the math again:

(320*1)/320 = 1           //viewport is smaller than 768px
(640*1)/320 = 2           //viewport is smaller than 768px
(960*0.5)/320 = 1,5     //viewport is smaller than 1200px

With this math we can see that viewports at 320px and 640px are actually pretty predictable. A viewport with 960px is a strange case. The browser will either pick the 320w image or the 640w image. I would expect the 640w image because 1.5 can be easily rounded to 2 but it's up to the browser to implement this.

Using the srcset

I feel like it's pretty save to go ahead and use the srcset right now. The fallback is good since it's just a regular tag with a source attribute set on it. However, do make sure that you sort off understand how a browser might interpret your srcset. It could save you many headaches and it will make you feel more confident about using it. if you want to know more about the srcset I strongly recommend reading You're just changing resolutions since it's a good description of how srcset works.

Questions, comments, notes, feedback, it's all welcome. You can find me on twitter for that.