Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting em to px in Javascript (and getting default font size)

There are situations where it can be useful to get the exact pixel width of an em measurement. For example, suppose you have an element with a CSS property (like border or padding) which is measured in ems, and you need to get the exact pixel width of the border or padding. There's an existing question which touches on this topic:

How can i get default font size in pixels by using JavaScript or JQuery?

This question is asking about getting the default font size - which is necessary in order to convert a relative em value to an exact px value.

This answer has a pretty good explanation of how to go about getting the default font size of an element:

Since ems measure width you can always compute the exact pixel font size by creating a div that is 1000 ems long and dividing its client-Width property by 1000. I seem to recall ems are truncated to the nearest thousandth, so you need 1000 ems to avoid an erroneous truncation of the pixel result.

So, using this answer as a guide, I wrote the following function to get the default font size:

function getDefaultFontSize(parentElement) {     parentElement = parentElement || document.body;     var div = document.createElement('div');     div.style.width = "1000em";     parentElement.appendChild(div);     var pixels = div.offsetWidth / 1000;     parentElement.removeChild(div);     return pixels; } 

Once you have the default font size, you can convert any em width to px width by just multiplying the ems by the element's default font size and rounding the result:

Math.round(ems * getDefaultFontSize(element.parentNode))

Problem: The getDefaultFontSize is ideally supposed to be a simple, side-effect free function that returns the default font size. But it DOES have an unfortunate side effect: it modifies the DOM! It appends a child and then removes the child. Appending the child is necessary in order to get a valid offsetWidth property. If you don't append the child div to the DOM, the offsetWidth property remains at 0 because the element is never rendered. Even though we immediately remove the child element, this function can still create unintended side effects, such as firing an event (like Internet Explorer's onpropertychange or W3C's DOMSubtreeModified event) that was listening on the parent element.

Question: Is there any way to write a truly side-effect free getDefaultFontSize() function that won't accidentally fire event handlers or cause other unintended side effects?

like image 894
Channel72 Avatar asked May 05 '12 15:05

Channel72


People also ask

What is the default size of 1em?

1em is equal to the current font size. The default text size in browsers is 16px. So, the default size of 1em is 16px.

How do I make the default font size?

Go to Format > Font > Font. + D to open the Font dialog box. Select the font and size you want to use. Select Default, and then select Yes.

How do you calculate font size from em?

An em is equal to the computed font-size of that element's parent. For example, If there is a div element defined with font-size: 16px then for that div and for its children 1em = 16px .

Should font size Be in px or em?

If you use px as the unit for fonts, the fonts will not resize whereas the fonts with rem / em unit will resize when you change the system's font size. So use px when you want the size to be fixed and use rem / em when you want the size to be adaptive/dynamic to the size of the system.


2 Answers

Edit: No, there isn't.

To get the rendered font size of a given element, without affecting the DOM:

parseFloat(getComputedStyle(parentElement).fontSize); 

This is based off the answer to this question.


Edit:

In IE, you would have to use parentElement.currentStyle["fontSize"], but this is not guaranteed to convert the size to px. So that's out.

Furthermore, this snippet won't get you the default font size of the element, but rather its actual font size, which is important if it has actually got a class and a style associated with it. In other words, if the element's font size is 2em, you'll get the number of pixels in 2 ems. Unless the font size is specified inline, you won't be able to get the conversion ratio right.

like image 143
mgiuffrida Avatar answered Oct 02 '22 04:10

mgiuffrida


I have a better answer. My code will store the length of 1em (in CSS pixel px units in the JavaScript variable em:

  1. Place this div anywhere in your HTML code

    <div id="div" style="height:0;width:0;outline:none;border:none;padding:none;margin:none;box-sizing:content-box;"></div> 
  2. Place this function in your JavaScript file

    var em; function getValue(id){     var div = document.getElementById(id);     div.style.height = '1em';     return ( em = div.offsetHeight ); } 

Now, whenever you will call this function 'getValue' with id of that test div in parameter, you will have a variable name em which will contain value of 1 em in px.

like image 21
10011101111 Avatar answered Oct 02 '22 03:10

10011101111