← / log / 25th Sep, 2007 /
Almost a year ago, Ty Gossman over at Stylegala asked me to write an article about elastic layouts. The best I could do was a quick email between work. I always meant to come good on that. Thanks for asking; sorry it took so long.
Also available in:
This article will walk you through creating a basic elastic layout; what exactly an “em” is and how to calculate them, how to use ems to create an elastic layer for content with scalable text and images, including basic vertical rhythm.
An elastic layout scales with users’ text size.
More accurately, an elastic interface scales with browser text size—commonly a default of 16px—which users can change if they wish. Some people make a permanent change for accessibility reasons, others use the UI controls to increase text size if they need to.
Elastic design uses em values for all elements. Ems are a relative size, written like this: 1em
, 0.5em
, 1.5em
etc. Ems can be specified to three decimal places like so: 1.063em
. “Relative” means:
<div>
has a computed font size of 16px then any element inside that layer —a child— inherits the same font size unless it is changed. If the child font size is changed to 0.75em then the computed size would be 0.75 × 16px = 12px.See the elastic layout example. Adjust text size to see it scale. It contains all the CSS and HTML used in this tutorial.
For other live elastic examples, visit Dan Cederholm’s beautiful and elastic SimpleBits, or resize text on this site.
Elastic interfaces are flexible and accessible for users, and can be almost as precise as pixels for designers. Layouts can be created accurately and quickly using CSS once we grasp the basic relationship between font size, pixels and ems.
The em is as powerful and flexible as Elastigirl, she doesn’t mind what the font size is, whether 12px, 16 or 60, she will always be exactly equal to it.
The em is a unit of measurement in typography. What is it and how did it get its name? Here’s a little history:
An em was originally equal to the size of the metal block used to cut a single letter of type for a specific font. It was roughly equivalent to the width of a capital letter “M”.
Further em reading:
Those with designers’ eyes amongst you might be saying, “hold up a second, letters don’t take up equal space.” You’d be right: Computers use kerning to adjust the horizontal space each letter occupies on the screen, making them equidistant and balanced. Originally, the metal block was trimmed or “kerned” to make the horizontal padding around each letter the same.
So, in CSS, an em is actually a vertical measurement. One em equals the vertical space needed for any given letter in a font, regardless of the horizontal space it occupies. Therefore:
If the font size is 16px, then 1em = 16px.
Before we start throwing ems around a stylesheet, we need to know what the default font size is in the browser. Luckily, we do:
All popular browsers have a default font size of 16px. Therefore, at the default browser setting, 1em = 16px.
In Firefox, you can check default font size via Tools > Options > Content.
So, before a single CSS selector is written, the browser has a 16px deafult font size. The <body>
inherits it unless styled otherwise using CSS. Therefore 1em = 16px, 0.5em = 8px, 10em = 160px and so on. We can now specify any element size we need to using ems!
Some erudite folks suggest setting the <body>
font size to either the required font size for body text, or the equivalent of 10px (0.625em or 62.5%) to make calculating child lengths easier. Both have merit, but it seems more logical to me to leave it at the browser default and change it for child elements if necessary.
So, we know that the body font size will be 16px by default. We also know that if a person has changed their settings, our elastic interface will not break, but adjust. Perfect, so we can set:
body{ em; }
However, (gasp) IE has a problem with ems. Resizing text from medium (default) to large in IE5/6 would lead to a huge increase in font size rather than the gradual one expected. So another selector is needed to get IE to behave:
html{ %; }
As Patrick H. Lauke previously pointed out, it’s an IE correction, not a hack—it doesn’t rely on a browser bug to work.
IE will now behave and resize text gracefully, rather than in mighty leaps of stupefying grandeur.
Let’s give our <body>
some more style, and center everything in the viewport (this will be important later for our content wrapper.) Our initial CSS ends up like this:
html{
%;
}
body{
em;
font-family: georgia, serif;
text-align: center;
color: #444;
background: #e6e6e6;
padding: 0;
margin: 0;
}
When first creating elastic pages, you will find yourself doing calculations a lot. Keep a calculator handy.
Tip: Find font size for any element with Chris Pederick’s brilliant Web developer toolbar using: Information > Display element information.
I am no maths wizard, so I needed a simple formula to remember. As a designer, I know pixels intimately, so that’s where I start. I calculate what 1px is in ems and multiple by the pixel size I need. That gives me the equivalent em value. We know that 1em is always equal to the font size of the parent element, therefore:
1 ÷ parent font-size × required pixel value = em value
For your bookmarks: Pixel to ems conversion table for font sizes.
Don’t let my talk of forumla put you off. Elastic interfaces are a joy to build so let’s get practical and create some page elements.
To create the centred content layer in the example, we need a little HTML. Let’s be really imaginative and give it an ID of “wrap”:
<div id="wrap">
…
</div>
We want it to be 740px wide to comfortably fit an 800×600px viewport like the example. What is 740px in ems? Let’s find out:
We know that the parent element (<body>
) has a font size of 16px. Our child layer (<div id="wrap">
) will inherit it. So we can calculate what 1px is in ems:
1em = 16px. Therefore, 1px = 1 ÷ 16 = 0.0625em.
Ems allow only three decimal places. More is fine in calculations but before writing CSS, round it up to three.
Then multiply by 740 to get ems:
0.0625em × 740 = 46.25em
Or do the whole calculation in one go with the formula:
1 ÷ 16 × 740 = 46.25em
(1 ÷ parent font-size × required pixel value = em value)
You can use the same formula to calculate ems for any width or height you need. Find 1px is in ems for that element. Multiple that by the pixel value you require to get the em equivalent.
Apply the width in ems, center the layer in the viewport using the auto left and right margins, give it a 1px gray border with a white background and align the text left:
#wrap{
.25em;
margin: 1.5em auto;
border: 0.063em solid #ccc;
background: #fff;
text-align: left;
}
Now we have an elastic wrapper for our content!
Let’s insert a <h1>
and a <p>
to our wrapper like so:
<div id="wrap">
<h1> … <h1>
<p> … <p>
</div>
Essential reading:
The Elements of Typographic Style applied to the Web created by Richard Rutter based on the masterwork by Robert Bringhurst.
While we're here, we might as well add some typographic goodness by selecting a basic leading and adding some vertical rhythm, with everything expressed in ems. Here’s a little more history:
Leading (pronounced “led–ing”) was traditionally the insertion of lines of lead underneath rows of text. It is expressed in CSS as line-height
but instead of adding space below, it increases the space above and below each line of text.
In the example, I’ve used the same font sizes as Richard Rutter did in his outstanding chapter on vertical motion to make your reading as consistent as possible. The heading font size will be 18px. The paragraph font size will be 12px with an 18px line height. 18px will be our basic leading—the most important value for our interface. Everything else will be proportional to that.
A note on CSS inheritance: Our content wrapper, <div id="wrap">
, has no font size set so it has inherited the 1em (16px) font size from its parent, the <body>
. Any elements within our wrapper will also inherit that font size, unless we tell the browser otherwise, as we’re about to do.
We know that our paragraphs have inherited a 1em (16px) font size from its parent, <div id="wrap">
. From our previous calculation, we already know that 1px is 0.0625em. We simply multiple that by 12 to get the em value for 12px:
0.0625 × 12 = 0.750em
Or do the whole calculation in one go with the formula:
1 ÷ 16 × 12 = 0.750em
(1 ÷ parent font-size × required pixel value = em value)
Then apply that to the CSS:
p{
.750em;
}
Margin, line height, padding etc. in ems are all relative to the font size of the element they belong to.
To calculate the desired line height and margin of 18px for our basic leading we do the following:
18 ÷ 12 = 1.5em
Dividing the desired line height (18px) by the element font size (12px) gives us the em value for line height. In this example, the line height is 1 and a half times the font size: 1.5em.
Add line height and margin properties to the CSS:
p{
.750em;
line-.5em;
margin: 1.5em;
}
Now the browser will say to itself, “Oh, line height and margin is set to 1.5em, so that should be 1.5 times the font size. What’s the font size, again? 12px? OK, cool, make line height and margin 1.5 times that, so 18px.” It will do all that faster than Dash too, and render it. Wow.
<h1>
:
The <h1>
has inherited a 1em (16px) font size from it’s parent, <div id="wrap">
. So, we already know what 1px is from before: 0.0625em. We simply multiple that by 18 to get the em value for 18px:
0.0625 × 18 = 1.125em
Or do the whole calculation in one go with the formula:
1 ÷ 16 × 18 = 1.125em
(1 ÷ parent font-size × required pixel value = em value)
Then apply that to the CSS:
h1{
.125em;
}
To retain our vertical rhythm we want to set an 18px line height and margin. Easy: If the font size is 18px then 18px in ems is 1em! Let’s add the properties to the CSS (and make the font weight light:)
h1{
.125em;
line-em;
margin: 1em;
font-weight: 300;
}
We now have vertical rhythm! Let’s move on to images.
To retain the rhythm of the the example page, the size of an image should be a multiple of the basic leading.
Our image has a width and height of 90px (18px × 5.) It has right and bottom margins of 18px and is floated left in the paragraph text. This is the HTML:
<p>
<img src="/img/spacer.gif">
The image is a child of the paragraph—it’s parent—so we know that the image has inherited a font size of 12px. Therefore, to calculate the image width and height we do the following using the formula:
1 ÷ 12 × 90 = 7.5em
(1 ÷ parent font-size × required pixel value = em value)
Then apply that to the CSS:
p img{
.5em;
.5em;
}
We already know what 18px is in ems for the parent paragraph, so let’s add the margin property (and the float) to the CSS:
p img{
.5em;
.5em;
margin: 0 1.5em 1.5em 0;
float: left;
}
N.B. The image does not need to be within a paragraph to give it semantic meaning. The was used in this instance as an example of how to take inheritance into account whilst calculating ems.
Now we have a supersuit elastic container with some elastic content and vertical rhythm like the example. With a bit of a luck, you have a better insight into creating elastic layouts, and designing with ems in particular. We’re done, you’re the Edna Mode of designers! The elastic example page has all the HTML and CSS you need. View source to grab it.
Some of the benefits of elastic design for designers are precision, control and accessibility. However, some people have expressed concerns that allowing the content to expand past the edge of the viewport at larger text sizes could be problematic. Also, text will sometimes wrap and flow within the framework when the text size is changed; a minor issue, but worth noting.
Concerns have also been expressed over the loss of image fidelity at increased text size. However, if a person changes their text size, the chances are they will also benefit from larger images, and browsers get better at resizing images as they increase in size. Hopefully browsers will get even better at resizing, or maybe we’ll soon have SVG and scalable background images to use.
Implementing elastic design can deliver a deep understanding of ems in CSS. It definitely has a place in every designer or developer’s toolkit, whether in combination with other techniques in hybrid layouts or on its own.
Any omissions or errors in this article are my own, so please let me know if I’ve missed something. If you know of other good and relevant resources elsewhere, please add them to the comments or email me and I’ll include them.
I also take full responsibility for all refences to The Incredibles—my 2 sons gave kind permission for me to use their figures for the title image—and I hope Elastigirl doesn’t mind being compared to the em unit.
Also, translated into Italiano by Nicola Pressi, and Deutsch by Pascal Birchler.
If you are bilingual and would like to translate this article for non English speakers, please download my vCard via the about page and contact me. Thanks!
79 Comments
1. By Chris Shiflett on 25th Sep ’07 at 05:33am
2. By Volkan Görgülü on 28th Sep ’07 at 09:03am
3. By Jon 陳 on 28th Sep ’07 at 16:51pm
4. By TheTyG. :) on 5th Oct ’07 at 08:48am
5. By Paul on 5th Oct ’07 at 11:03am
6. By patrick h. lauke on 7th Oct ’07 at 05:14am
7. By Jon 陳 on 8th Oct ’07 at 01:14am
8. By Malte on 14th Oct ’07 at 09:32am
9. By Adam Twardoch on 19th Dec ’07 at 00:01am
10. By Jon 陳 on 19th Dec ’07 at 02:39am
11. By Online Druckerei on 26th Dec ’07 at 06:03am
12. By Gordon Mackay on 1st Jan ’08 at 04:58am
13. By Ralph on 21st Jan ’08 at 02:12am
14. By Joshua Gay on 21st Jan ’08 at 15:48pm
15. By Jon 陳 on 22nd Jan ’08 at 05:59am
16. By baby on 23rd Jan ’08 at 05:28am
17. By Paul Walker on 26th Jan ’08 at 05:00am
18. By Property Investment Guy on 28th Jan ’08 at 08:31am
19. By Ian Sutherland on 30th Jan ’08 at 13:36pm
20. By Ryan on 4th Feb ’08 at 10:20am
21. By Ty on 6th Feb ’08 at 11:48am