View Full Version : How to calculate the pixel to em ratio
brothercake
08-06-2003, 12:19 AM
I was thinking, draw an invisible, absolutely positioned element that's 10em wide, and then read its offsetWidth to work out the ratio.
But is there a cleaner way - a purely mathematical way or a system property?
Not really. em is a relative unit, so it's size actually depends on where the style is being applied (should be on what font is currently applied methinks).
You could do something like:
var widthProp = document.defaultView.getComputedStyle(document.body, '').getPropertyCSSValue("width");
var pxOverEm = widthProp.getFloatValue(CSSPrimitiveValue.CSS_PX) / widthProp.getFloatValue(CSSPrimitiveValue.CSS_EMS);
But the only browser remotely close to this capability is Mozilla, and Mozilla chooses to throw a DOMException instead of converting to other units. And this would be em relative to the body of the document.
brothercake
08-06-2003, 04:47 AM
Originally posted by jkd
Not really. em is a relative unit, so it's size actually depends on where the style is being applied (should be on what font is currently applied methinks).
Oh, I hadn't thought of that, but maybe it's okay ...
The bottom line of what I wanna do ... you'll laugh ... is make "max-width" work in IE :D Here's the plan:
Say max-width is defined as 8em, I let the element render at "width:auto" and then read its offsetWidth; assume for now I already have the em-px ratio, I just have to work out 8em in pixels, see if the offsetWidth is greater, and apply 8em width if it is.
But getting that ratio - if I create a hidden element inside the element which will eventually have max-width applied, then the em-px ratio will be correct in the context of that element, which is all I need to know.
Does that make sense? Or is there a flaw in my logic ...?
Originally posted by brothercake
But getting that ratio - if I create a hidden element inside the element which will eventually have max-width applied, then the em-px ratio will be correct in the context of that element, which is all I need to know.
That works. You'll have momentary overflow though, which may or may not be an issue depending on how flawless a presentation you need.
brothercake
08-06-2003, 08:03 AM
Unless .. if the element is positioned, then the test element can be absolutely positioned inside it, so no displacement :)
Originally posted by brothercake
Unless .. if the element is positioned, then the test element can be absolutely positioned inside it, so no displacement :)
Ohh, crafty. :D
brothercake
08-07-2003, 07:15 AM
Excellent .. here's the method; I'm just copying this out of a larger script, where "udm" is the main object, "udm.tree" is the <ul> element, and udm.navbarStyles[0] is the defined value for max-width; it happens as the nav is loading - it has to be displayed but it can be invisible - then iterate through the first-level links and pass them to the method; setting a class whose width is the same as max-width means I don't even have to work out the ratio - just measure the created object - so it works for % as well :)
//apply max width for IE
udmNavbar.prototype.applyMaxWidth = function(udmLink)
{
//if we don't yet know the max width in pixels
if(udm.maxWidth == 0)
{
//create an element inside the tree
udm.testEle = document.createElement('div');
udm.tree.appendChild(udm.testEle);
//and set it to a test class whose width is the value of max-width
udm.testEle.setAttribute('class','');
udm.testEle.className = 'udmUnitTest';
//now measure it in pixels
udm.maxWidth = udm.testEle.offsetWidth;
//now remove it
udm.tree.removeChild(udm.testEle);
}
//get the link element width in pixels
udm.linkWidth = udmLink.offsetWidth;
//if it's greater than the equivalent max-width
if(udm.linkWidth > udm.maxWidth)
{
//apply max-width
udmLink.style.width = udm.navbarStyles[0];
}
}
All of that just for "max-width" bla"... makes you really wish IE wasn't dominate... but a nice little hack nonetheless. :)
brothercake
08-07-2003, 07:23 AM
Tell me about it ... it's sooo tedious ... but having this means I can make a list-based horizontal navbar which can be generated from a database :) Without it, either all the cells would have to be fixed width, or there's the possibility of overlong links making the navbar too wide for the page.
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.