jQuery/JavaScript: convert pixels to em in a easy way jQuery/JavaScript: convert pixels to em in a easy way javascript javascript

jQuery/JavaScript: convert pixels to em in a easy way


I think your question is very important. Since the classes of display resolutions are rapidly increasing, using em positioning to support wide range of screen resolutions is a really appealing approach. But no matter how hard you try to keep everything in em -- sometimes you get a pixel value maybe from JQuery drag and drop or from another library, and you would want to convert this value to em before sending it back to server for persistence. That way next time user looks at the page, item would be in correct position -- regardless of screen resolution of the device they are using.

JQuery plugins are not very scary when you can review the code, specially if they are short and sweet like this plugin to convert pixel values to em as you want. In fact it is so short I will paste the whole thing here. For copyright notice see the link.

$.fn.toEm = function(settings){    settings = jQuery.extend({        scope: 'body'    }, settings);    var that = parseInt(this[0],10),        scopeTest = jQuery('<div style="display: none; font-size: 1em; margin: 0; padding:0; height: auto; line-height: 1; border:0;"> </div>').appendTo(settings.scope),        scopeVal = scopeTest.height();    scopeTest.remove();    return (that / scopeVal).toFixed(8) + 'em';};$.fn.toPx = function(settings){    settings = jQuery.extend({        scope: 'body'    }, settings);    var that = parseFloat(this[0]),        scopeTest = jQuery('<div style="display: none; font-size: 1em; margin: 0; padding:0; height: auto; line-height: 1; border:0;"> </div>').appendTo(settings.scope),        scopeVal = scopeTest.height();    scopeTest.remove();    return Math.round(that * scopeVal) + 'px';};

Usage Example: $(myPixelValue).toEm(); or $(myEmValue).toPx();.

I just tested this in my application, it works great. So I thought I share.


The following seems to do as you require, though it's based on the font-size of the parent, and of the element itself, being returned in px:

function px2em(elem) {    var W = window,        D = document;    if (!elem || elem.parentNode.tagName.toLowerCase() == 'body') {        return false;    }    else {        var parentFontSize = parseInt(W.getComputedStyle(elem.parentNode, null).fontSize, 10),            elemFontSize = parseInt(W.getComputedStyle(elem, null).fontSize, 10);        var pxInEms = Math.floor((elemFontSize / parentFontSize) * 100) / 100;        elem.style.fontSize = pxInEms + 'em';    }}

JS Fiddle proof of concept.

Notes:

  • The function returns false, if the element you're trying to convert to em is the body, though that's because I couldn't work out whether it was sensible to set the value to 1em or simply leave it alone.

  • It uses window.getComputedStyle(), so it's not going to work with IE, without some adjustments.

References:


Pixels and ems are fundamentally different types of unit. You can't simply convert between them.

For instance, a user with a default font size of 16px on a site where top-level headings are styled at 200% font size, 1em may be equal to 32px. Move the heading elsewhere in the document, it could be 64px or 16px. Give the same document to a different user, it might be 30/60/15px. Start talking about a different element, and it can change again.

The closest you can come to what you want is to convert from pixels to ems+document+context+settings. But if somebody has asked you to lay out your project with ems, they will probably not be pleased that you are trying to do it in pixels then "converting".