Friday, March 17, 2006

How Many Pixels in an EM? Part 2

Yesterday, I blogged about a formula I came up with for determining the number of pixels in an em. Jan commented that perhaps this approach isn't such a good idea, because it might break when someone changes the font-size of their OS. This is actually not the case: changing the font-size in your OS doesn't change the pixel size of a point or an em.

However, Jan's comment prompted me to dig a little deeper. Can the size of an em change based on the screen resolution? Turns out, it does. At least according to this article, which I can only assume is correct given my lack of different displays to test it on. About mid-way down the page, in a lovely yellow block, is the following critical information:

Pixels per em is a crucial concept. As much as any other single factor
(such as ex-height), it determines the legibility of characters on screen at a nominal point size. The higher the ppem, the better defined are the characters' features, and the more and larger decrements are possible before hitting the legibility floor. If the ppem of the base size is low, fewer and smaller steps are
possible.

Pixels-per-em refers to the number of screen pixels required to render the em of a font at a size given in points.

A point is 1/72". On a system displaying 72 pixels per logical inch (Mac OS standard ppi), 1 point equals 1 pixel. On a system displaying 96 or 120 ppi (standard Windows settings), 1 point equals 1.333 or 1.667 pixels, respectively. The formula for ppem is a(b/72), where a is the font size, and b is the logical resolution figure.

For example, 12 points at 72 ppi (the legacy Mac OS browser default) or 9 points at 96ppi have a ppem value of 12. Twelve points at 96ppi (the legacy Windows browser default), or 16 points at 72ppi both have a ppem of 16. Twelve points at 90ppi have 15ppem, and 12 points at 120 ppi (Windows "large fonts") have 20ppem.


Nice. This both proves my formula, and puts a monkey wrench in it. If someone has changed their display resolution from the Windows default 96ppi, the formula is no longer accurate.

All is not lost. Since we're dealing with an IE-only expression to begin with, we can take advantage of an IE-only JavaScript property, screen.deviceXDPI. Our expression becomes:

width:expression( document.body.clientWidth >
(30*(screen.deviceXDPI/72))* parseInt(document.body.currentStyle.fontSize)?
"30em": "auto" );

This expression would yield a max-width of 30em. Naturally, it couldn't be this easy... Now, the expression no longer works in IE 5 or IE 5.5 because they don't support our new best friend, the deviceXDPI property. Well, I don't have too much of a problem with that. Out of the 5% or so of my visitors who have IE5 or IE5.5, how many of those would also have changed their display DPI? I think not many. But, just so the expression degrades well, let's test for the existence of the deviceXDPI property and adjust accordingly:

width:expression(document.body.clientWidth >
(30*((screen.deviceXDPI?screen.deviceXDPI:96)/72))*
parseInt(document.body.currentStyle.fontSize)? "30em": "auto" );

In this (increasingly long) expression, if screen.deviceXDPI is undefined, the default value of 96ppi is used. That oughtta do it. Comments?

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

2 Comments:

Blogger Digital Dreams said...

Hi,
Could you please help me fixing my blog's headef width issue?

The width is perfect in firefox and opera,whereas width is high in IE.

Thanks
publisher-Digital dreams
http://techbeam.blogspot.com

3:22 AM  
Blogger Unknown said...

Hi,
I am trying to provide multi-lingual support to my product. The Formula suggested in the article is working for european languages but fails for chinese, japenese and korean language. The chinese and japenese strings are not accomodating in the components Can you suggest me formula which can work for both CJK and european languages.
Thanks in advance.
Vishesh

10:56 PM  

Post a Comment

<< Home