Retaining scalable interfaces with pixel-to-em conversion

Posted by Scott on 03/04/2008

Topics:

Note: This post is outdated. You can find the newest article here: Update: jQuery Plugin for Retaining Scalable Interfaces with Pixel-to-Em Conversion.

We developed a script to quickly convert pixel to em values (and vice versa) so that page scalability can be retained throughout a web site or application. The script appends a method to the native string object and uses jQuery selectors to scope the em conversion to a particular element.

Why Ems, Anyway?

In CSS layouts, ems are often used in place of pixels to allow elements and text to scale in unison. Although pixels tend to be easier to use and more precise, many browsers such as Internet Explorer can not scale text that is set in pixels. By using ems for not only our text, but for setting the heights and widths of structural elements, some or all of the page layout can also scale in proportion to the text size.

How do they work?

In brief, an em is a relative unit that is equivalent to the height of a font. Since most browsers' default font size is 16px, we can assume that 1em is equal to 16px; meaning that 12px is equal to 0.75em, and 10px type is equal to 0.625em. As you can see, it can be quite tedious to calculate em values this way, and luckily a method was developed by clagnut to alleviate the problem. By simply setting the body element's font size to 62.5%, the value of 1em becomes 10px. This allows for nice and easy calculations to ems by simply dividing a pixel value by 10.

While that cuts down on some of the conversion work, the value of 1em can still vary depending on parent/child relationships in the DOM. For every element on the page, the value of 1em is calculated based on the font size of its parent element. This means that while a paragraph may have a font size of 1.2em and appear to be 12px tall, all of its children will exist in a world where 1em is equal to 12px instead of 10. Which, in a way, leads us back to where we started.

Where Ems are Often Abandoned

Managing an em-based stylesheet may be confusing, but it usually doesn't cause any major setbacks to web developers. We find that the problems more often occur when elements are inserted or modified with javascript. During animation effects or modifications to the DOM, many javascript libraries style elements using pixels to avoid the possibility of conflicts, and while pixels are often desired and are a good default, we usually want our modifications to fit within a scalable interface. For this reason, we've come up with a method that converts pixel values to ems on the fly, and always calculates within the scope it is given.

So how does it work?

When called, pxToEm converts a given pixel value to ems. By default, it uses the body's font size for scope, but a scope property (in the form of a jQuery selector) can be passed to handle conversions that are relative to that element's font size.

Sample Output:


var pixelValue = 256; 
var emValue = pixelValue.pxToEm(); 
==> returns '25.6em'

The sample above may look like a simple division of 10, but the script actually checks the font size of the body before calculating so it will work in many environments. To demonstrate how scope is used, consider the following example which uses a scope property:

Sample Output Using a Scope Element:


var pixelValue = 256;
var scopeElement = $(myElement); //element being used for scope. It has a font size of 14px.
var emValue = pixelValue.pxToEm({'scope': scopeElement}); 
==> returns string "18.29em"

We can see that pxToEm has used the font size of the scope element for its calculation above. Using a scope parameter may be particularly useful for figuring out dimensions when inserting an element into the scope element.

But What About Ems to Pixels?

Don't worry, we didn't leave you hangin'! A second optional property called 'reverse' defines the direction of the conversion. Pass a reverse parameter as true and pxToEm will convert your em value to pixels. The following calculator demonstrates the flexibility and capabilities of this plugin.

Demo Calculator

Demo page

Sweet! How do I use it?

First, you'll need to be using the jQuery javascript library, which is free and can be downloaded here: jQuery.com. Then grab one of the javascript files linked below and either paste its contents into your javascript file or link to it as a standalone.

Syntax and options

Unlike a jQuery plugin, pxToEm is a string/number method and is not meant to be applied to a jQuery object. Instead, you will apply it as a method on a variable that references either a number or numeric string. pxToEm has defaults that can be overridden via the options argument. These settings should be passed in as an object as shown below:


myValue.pxToEm({
   scope: 'h3',
   reverse: true
});


Available Options

  • Scope: jQuery object or selector string, defaults to 'body'
  • Reverse: Boolean, defaults to true

Download it!

Book cover: Designing with Progressive Enhancement

Enjoy our blog? You'll love our book.

For info and ordering: Visit the book site

Comments

Just fyi, a very common method to get this same “easy” conversion (the .625em = 10px default) AND to both allow the body font size to remain close to normal and to address a bug in some IE browsers that sometimes allows em-based sizing to go very miniscule is to set the body font-size to 101%, then place a .625em size on the #wrapper or #wrap (if in wordpress)…

Then the basic font size does become that easy-to-use 10px, since that is now the default size. Setting heading, paragraph and other font-sizes for elements becomes a matter of translating 1em=10px or 1.2em=12px, etc.

I’ve used this since I began developing css-based layouts. By zeroing out all the default values for elements early in your style sheet and setting the font-size to 1em, every element inside the #wrapper or #wrap (whatever you are using to contain your site elements in the page) defaults to the 10px value, including headings.

I’ve not run across the issue you’ve described with respect to IE browsers converting em widths to some value based on the body width of the page… perhaps because I DO reset the defaults for every element to 1em (101%) then convert that to 10px in the #wrapper?

I’ll have to experiment with this idea. Thanks for the effort; I’m looking forward to playing with it.

Comment by Casey on 12/16  at  08:33 PM

I’ve used this since I began developing css-based layouts. By zeroing out all the default values for elements early in your style sheet and setting the font-size to 1em, every element inside the #wrapper or #wrap (whatever you are using to contain your site elements in the page) defaults to the 10px value, including headings. Very interesting and useful tips,
so many helpful informations include in this article!
Thanks for good items! This looks good! Excellent SITE.

Comment by energy certificate on 01/02  at  12:38 AM

thanks you very mach :)

Comment by parça kontör on 01/02  at  04:22 PM

Wow a fantastic site, I loved it when I landed on it. I could never do anything like this, maybe I should open a competition for someone to redesin mine.

Comment by strony internetowe gdańsk on 01/14  at  01:29 PM

Thanks for this article, it’s great. So great that we’ve made it ‘sticky’ on The Webmaster Forums. Now we don’t have to repeat ourselves, just send people to this article!

Comment by strony internetowe flash on 01/15  at  11:21 PM

I’ll have to experiment with this idea. Thanks for the effort; I’m looking forward to playing with it.

Comment by amber gifts on 02/06  at  01:04 AM

Thanks for good items! This looks good! Excellent SITE.

Comment by obsługa kart płatniczych gdańsk on 03/13  at  10:57 AM

thanks for the great post.
is there any pt to em conversion? (not px to em)

Comment by brian on 04/06  at  04:28 AM

Amazing article and tips to conversion.
Pretty Useful.

Thanks.

Comment by como emagrecer on 08/04  at  06:46 PM

Excellent article. I always used measured in pixels but this causes problems when users change the size of their sources and view the site. Had already thought about the possibility of using the measures in EM and now it’s much easier. Thanks

Comment by Loja virtual IpHouse on 09/03  at  05:40 AM

I really needed an explination of the “em” notion and why it’s used. Thanks a lot! Cheers

Comment by Valea Prahovei on 10/29  at  03:37 PM

Thanks for the tips. really useful indeed

Comment by Case de Vacanta on 11/12  at  02:49 PM

Thanks for the article!

Comment by Filme Noi on 11/18  at  12:01 AM

you might find this useful as well. http://pixel2em.kleptomac.com
This provides an online pixels to em converter and you can also do a complete css file conversion.

Comment by Jai on 01/30  at  08:06 PM

good good good job my boy. like the article - very helpful

Comment by fotowoltaika on 08/01  at  05:40 PM

Internet Explorer certainly did cause a lot of inconsistencies in sizes set by pixels.  For the longest time I didn’t know why it was doing that. Now I found out how Firefox in PC and Firefox in Mac renders image sizes slightly different for forms.  I will try to use em and hopefully that will uniformly set the size again.

Comment by Peter on 05/17  at  05:42 PM

Thanks, everyone, for the feedback.  We’ve closed comments on this post. 

We’ve updated our technique for pixel-to-em conversion here: Update: jQuery Plugin for Retaining Scalable Interfaces with Pixel-to-Em Conversion

Comment by Maggie (Filament) on 06/23  at  07:28 PM

Book cover: Designing with Progressive Enhancement

Enjoy our blog? You'll love our book.

For info and ordering: Visit the book site