Taking the “Erm..” Out of Ems
I'm going to make a sweeping statement; pixels have no place in web design. There's only one reason you're still relying on pixels – and that's because you haven't yet gotten the hang of ems. Let's change that!
However, it turns out that pixels are inherently inflexible. And it turns out that being inflexible isn't great for the web.
Browsers display body copy at a default size. On desktops this is generally 16px, mobile browsers vary. Users can change this default, depending on what they prefer.
Often, web designers will use CSS to cast the base font size in stone..
..preventing the user from tailoring their own reading experience, ultimately making the content less accessible.
Lesson one is in handing power back to the user. Don't prevent users from setting their own type size, but make sure you begin on a level playing field. Set your base font to 100% of the browser default:
then we can work from there.
These figures have been used for centuries, calculated in order to optimize proportions, without having to physically manufacture too many of the blocks used in printing. There's all kind of clever mathematics which justify scales like this and I'm sure you can appreciate that this range is pleasing to the eye too.
We would translate this scale to our own typography by applying CSS a bit like this:
However (as we've said already) using fixed pixel values is inflexible, so let's rectify that..
1em is equal to the inherited font size. If the font size of a
Ems get their name from printing. Precisely when the term was first used is unclear, but as the uppercase M (pronounced emm) most closely represents the square printing block on which printing letters were placed, it came to lend its name to the measurement. Whatever the point size of the font in question, the block of the uppercase M would define the Em.
An em is usually a touch larger than the letterform, but you get the idea.
Using the body size we assume to be 16px, aiming to convert our 36px
Here's how our scale is converted, using the method above:
Some of these values can get a little complex, but don't be afraid to be as precise as possible with the decimal places. Browsers will always do their best to render the exact values.
Tip: It's often useful to make a note in the comments, to remind yourself how you calculated each em value.
Now take a look at this innocent piece of markup:
As you'd expect, all appears well in the browser. Both the paragraph and the anchor are displaying at 1.2em, relative to the body font size
However, if we were to introduce a second anchor within the paragraph, let's see what happens:
The anchor within the paragraph is still sized at 1.2em, but that's now relative to the parent paragraph, which is already 19.2px -
Note: Nested list items in navigation menus are a classic example of where cascading can get out of control - watch out for that one.
There's no fixed rule for how large line-height should be, but 1.5em is a reasonable value to try out and will make your typography pleasantly readable.
Tip: Take a look at Bryan Gruhlke's suggestion in the comments for using unit-less values with line-height..
Note: Things can get complicated if you're trying to set a baseline grid with ems, but that's a topic for another article.
If we're talking about fluid layouts, you should be using % values to determine the width of any given element. Pixels should be nowhere to be seen when determining horizontal dimensions.
Vertical spacing can be achieved very easily with ems; again, it's a question of being clean with your markup and styling. Consider restricting margins to the bottom of your elements, so as to make managing vertical rhythm easier.
If you need to define a
Rounded corners on a button? Set the
Text shadow, box shadow, ditto.
In this case, you simply won't see it.
For horizontal rules, you may have styles a bit like this:
In order to prevent it disappearing when the body size is too small, you could add this:
There. A pixel. Dangit.
Border widths cannot have a minimum value (sadly) so a similar backup in that case isn't possible. Instead, you could use the border width values of
If you can think of a situation where you simply can't use ems, I'd love to hear it in the comments!
Size is Everything
When we build websites, we need to tell the browser how “big” stuff is: “this heading is so big”, “this container is yay high”, “this form is wider than that”, it's how we layout a page. Pixels have always made perfect sense as the chosen unit of measurement; we're outputting to a screen, so what else would we use?!However, it turns out that pixels are inherently inflexible. And it turns out that being inflexible isn't great for the web.
Problems with Pixels
Oliver Reichenstein stated a long time ago: “The Web is 95% Typography”, but it's taken a good few years for people to get on board with the idea. Content and users; they are our priorities as web designers, and typographic design helps us meet those priorities.Browsers display body copy at a default size. On desktops this is generally 16px, mobile browsers vary. Users can change this default, depending on what they prefer.
Often, web designers will use CSS to cast the base font size in stone..
..preventing the user from tailoring their own reading experience, ultimately making the content less accessible.
Lesson one is in handing power back to the user. Don't prevent users from setting their own type size, but make sure you begin on a level playing field. Set your base font to 100% of the browser default:
then we can work from there.
Our Typographic Scale
We still need to define how large our various typographic elements appear, especially if we've used a CSS reset technique to remove all default sizing. A fairly typical modular scale would look something like this:These figures have been used for centuries, calculated in order to optimize proportions, without having to physically manufacture too many of the blocks used in printing. There's all kind of clever mathematics which justify scales like this and I'm sure you can appreciate that this range is pleasing to the eye too.
We would translate this scale to our own typography by applying CSS a bit like this:
However (as we've said already) using fixed pixel values is inflexible, so let's rectify that..
Enter the Em
An em is a unit of measurement. Just like pixels, ems can determine the size of elements on a web page. Unlike pixels, which are absolute, ems are relative to their parent's font size, which is where a lot of confusion lies.1em is equal to the inherited font size. If the font size of a
<div>
is set to 16px, 1em within that <div>
is equivalent to 16px. If the font size of that <div>
changes to 20px, 1em within that <div>
is equivalent to 20px.Ems get their name from printing. Precisely when the term was first used is unclear, but as the uppercase M (pronounced emm) most closely represents the square printing block on which printing letters were placed, it came to lend its name to the measurement. Whatever the point size of the font in question, the block of the uppercase M would define the Em.
An em is usually a touch larger than the letterform, but you get the idea.
Conversion from Pixels
We've already started to set our typographic scale in pixels, so how do we convert that into ems? A simple calculation, which expresses the desired font size in relation to the body font size:Using the body size we assume to be 16px, aiming to convert our 36px
<h1>
, we get:Here's how our scale is converted, using the method above:
Some of these values can get a little complex, but don't be afraid to be as precise as possible with the decimal places. Browsers will always do their best to render the exact values.
Tip: It's often useful to make a note in the comments, to remind yourself how you calculated each em value.
Issues with Cascading
The number one biggest grumble people have with ems comes from complications which arise from cascading. An em value is relative to its nearest parent's value, which can accidentally mess things up if you're not paying attention. Take a look at the following css, which aims to get anchors and paragraphs sized equally:Now take a look at this innocent piece of markup:
As you'd expect, all appears well in the browser. Both the paragraph and the anchor are displaying at 1.2em, relative to the body font size
(1.2 * 16px = 19.2px)
.However, if we were to introduce a second anchor within the paragraph, let's see what happens:
The anchor within the paragraph is still sized at 1.2em, but that's now relative to the parent paragraph, which is already 19.2px -
(1.2 * 19.2px = 23.04px)
. This gives us extra large anchors in some parts of our page; hardly desirable.Note: Nested list items in navigation menus are a classic example of where cascading can get out of control - watch out for that one.
The Fix
There is no fix for this; the last thing you want to do is add an extra rule to decrease the size of anchors which happen to be in paragraphs - that's a one-way ticket to Migrainesville. In order to keep your CSS and HTML maintainable, it's important to Keep It Simple™.- Keep your markup simple and modular.
- Define your ems clearly and in a restrained fashion - don't go throwing them all over the place.
- Try to restrict font-sizes to typographic elements; be cautious of applying font-sizes to structural elements.
Rems
Rems are useful and behave in exactly the same way as ems, without the cascading. Every Rem you define is relative to the body font size. Support is nowhere near as good however, so IE8 and older will need a pixel-based fallback.What About Using Ems Elsewhere?
We've covered the CSSfont-size
property; a sensible first step into using ems, but now let's look at line-height
. If ever there was a property which screams "don't use pixel values", it's line-height. The line height (discussed during an earlier article in more detail) of a typographic element should always be relative to the font-size. If you have a heading whose size is set in ems, but whose line-height is set in pixels, you could end up with ugly overlapping and a poor visual relationship in general.There's no fixed rule for how large line-height should be, but 1.5em is a reasonable value to try out and will make your typography pleasantly readable.
Tip: Take a look at Bryan Gruhlke's suggestion in the comments for using unit-less values with line-height..
Note: Things can get complicated if you're trying to set a baseline grid with ems, but that's a topic for another article.
Structural Elements
Once you get into the mindset of keeping your layout flexible in terms of the font size, you'll find you rely on pixels less and less for laying out elements on the page.If we're talking about fluid layouts, you should be using % values to determine the width of any given element. Pixels should be nowhere to be seen when determining horizontal dimensions.
Vertical spacing can be achieved very easily with ems; again, it's a question of being clean with your markup and styling. Consider restricting margins to the bottom of your elements, so as to make managing vertical rhythm easier.
If you need to define a
height
(which can be tricky in flexible layouts) use ems too. Perhaps you're building a navigation and need to define the height of the menu links - they should grow and shrink with the font size.Rounded corners on a button? Set the
border-radius
using ems, so everything scales seamlessly.Text shadow, box shadow, ditto.
RWD
And if you need to change the size of everything under certain circumstances, like smaller viewports? Alter the base font size of the body in the appropriate media querybody { font-size: 90%; }
and wham! Your whole site scales in the time it takes to hit enter.Exceptions
Like all excellent scientific rules, there has to be an exception to prove it. In this case, I can think of one good scenario where you may need pixels; borders. If you define a border width (or the height of a horizontal rule) in ems, it may find itself being calculated so small that the browser can't render it.In this case, you simply won't see it.
For horizontal rules, you may have styles a bit like this:
01 02 03 04 05 06 07 08 09 10 | hr { height : . 02em ; border : none ; background : white ; margin : 2em 0 ; outline : none ; display : block ; clear : both ; width : 100% ; } |
1 | min-height : 1px ; |
Border widths cannot have a minimum value (sadly) so a similar backup in that case isn't possible. Instead, you could use the border width values of
thick
, medium
and thin
, although these values don't scale with font-size any better than pixels do.Conclusion
Start using ems today! Your content is typographically grounded, whether you realise it or not. Referring back to pixels, converting figures and thinking in terms of fixed layouts isn't even necessary. Begin thinking in ems and you'll soon forget pixels altogether.If you can think of a situation where you simply can't use ems, I'd love to hear it in the comments!
Comments
Post a Comment