Get the rendered style of an element

Published on Monday, April 24th, 2006

I guess most of you, one time or another, has had the need to find out what style was actually rendered on an element. The easiest way to do this is through the style property followed by the specific value you’re looking for:


	var intPosLeft = document.getElementById("left").style.left;

However, this only works if the CSS has been applied inline on the element. As we all (or at least most of us) have realized, having inline styles isn’t a very good and efficient approach. So then we move all our CSS to an external file and suddenly the style property return no values when checking it.

What the hell happened?

The style property is reserved for inline styles (ridiculous, if you ask me), so you need to find another way to do it. Of course, then, there’s one standard way and one Microsoft way.

I have put together a function named getStyle (yes, the name is supposed to be funny) to solve this issue for you:

I’ve updated one line for IE per zcorpan’s suggestion. The previous code worked fine as well, it’s just a matter of personal preference when it comes to code syntax.


function getStyle(oElm, strCssRule){
	var strValue = "";
	if(document.defaultView && document.defaultView.getComputedStyle){
		strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
	}
	else if(oElm.currentStyle){
		strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
			return p1.toUpperCase();
		});
		strValue = oElm.currentStyle[strCssRule];
	}
	return strValue;
}

It is then called, for instance, like this:


	getStyle(document.getElementById("container"), "font-size");

The first parameter is an object reference to the element you want to check, the second is the CSS name of the property you want to know the rendered value for.

Interesting to know is that specific values will return a value even if it was applied by shorthand in the CSS. For example, this will work just fine:


/* Element CSS*/
div#container{
	font: 2em/2.25em Verdana, Geneva, Arial, Helvetica, sans-serif;
}

var elementFontSize = getStyle(document.getElementById("container"), "font-size");

An other interesting thing is that Firefox, Opera and Safari will returned the actual pixels of a font size applied with em, while IE only return the value in em.

Web browser compatibility

This script has been tested to work in the following web browsers:

  • IE 5.5+
  • Firefox
  • Safari
  • Opera 8.5

The reason that it doesn’t work in IE 5.0 is having a function in the replace method as a second parameter. You might want to put this in a try...catch clause if you expect any users with that version, like this:


try{
	strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
		return p1.toUpperCase();
	});
	strValue = oElm.currentStyle[strCssRule];
}
catch(e){
	// Used to prevent an error in IE 5.0
}

 

Download the JavaScript file

Download the getStyle JavaScript file.

Posted in CSS, JavaScript | 36 comments

36 comments

  • Kristin
    April 24th, 2006 at 11:47

    Smutt Robert (smutt - swedish for nice)

  • David HÃ¥säther
    April 24th, 2006 at 13:29

    (smutt - swedish for nice)

    Huh? Never have I heard that :)

  • Tim Hofman
    April 24th, 2006 at 13:34

    I stumbled over this in one of my own projects. Like you said it is pretty ridiculous that the style property only works combined with inline stylerules.

    This function will sure come in handy, thanks!

  • Cameron Adams
    April 24th, 2006 at 16:18

    It’s not that ridiculous that .style only maps to inline styles — it’s really just a shortcut to the style attribute.

    Granted, it would be mildly less ridiculous if getting the computed style wasn’t so convoluted.

  • zcorpan
    April 24th, 2006 at 16:19

    Shouldn’t strValue = oElm.currentStyle[strCssRule]; work instead of using eval()?

  • Per Zimmerman
    April 24th, 2006 at 16:59

    Check out the FireFox extension CSSViewer, which does the same thing (at least some of it).

  • Patrick Fitzgerald
    April 24th, 2006 at 18:39

    Thanks for the code! I agree with the other poster: try to eliminate the “eval” (blech!)

  • gRegor
    April 24th, 2006 at 19:56

    Similarly, the Firefox extension View Source Chart displays the rendered source (including styles after applied to elements) of the entire document in a neatly structured view. Highly recommended.

  • Satunnainen Björklund » Elementin laskettu tyyli
    April 24th, 2006 at 22:32

    […]

    Satunnainen Björklund 24.4.2006 Elementin laskettu tyyli Robert Nyman: Get the rendered style of an element. Näppärää JavaScriptiä. […]

  • Robert Nyman - author
    April 24th, 2006 at 22:33

    Kristin, David,

    While I have heard that term, it doesn’t have a nice ring to it in English… :-)

    Tim,

    No problem, I hope it will be of use to you.

    Cameron,

    Logically, of course you’re correct. But, like you say, it’s probably because it’s so tricky to get the computed style that I’m opposed to that approach, plus the fact that no one uses inline styles anyay, so then style becomes obsolete.

    zcorpan,

    Yes, that works too. Didn’t think of it, but I like that syntax better, so I’ve updated the post and code per your suggestion.

    Patrick,

    Thanks! Code updated, although in general I don’t regard eval() as inherently evil… :-)

    Per, gRegor,

    Thanks for the information.

    Although, at least not to me, the purpose of this script isn’t just to see what’s rendered as general information, but to act on what value a certain style has got and then build on it in the current web page.

  • Andrew Tetlaw
    April 24th, 2006 at 23:50

    There’s also that oddball ‘float’ CSS property, in IE it’s ‘elm.styleFloat’ and in moz it’s ‘elm.cssFloat’.

    Might want to support that too.

  • Robert Nyman - author
    April 25th, 2006 at 9:15

    Andrew,

    That’s very true, thanks for pointing that out.

    I don’t think I’ll incorporate it in this script because a) I want to keep the function as simple and light-weight as possible and b) I think it’s something one rarely looks for thus the need isn’t that big.

    However, it’s very good to be aware of that difference.

  • Mislav
    April 25th, 2006 at 15:34

    This is exactly what Prototype library does with its Element.getStyle

  • Ash Searle
    April 25th, 2006 at 22:51

    Mislav,

    Not exactly… the code’s similar, but prototype’s getStyle is broken….

    prototype’s getStyle function checks element.style first, assuming that if a specific property is set inline it will override anything set in a stylesheet - and they then avoid a potentially slow call to getComputedStyle. This can produce the wrong result, as !important properties take precedence over inline styles. Unless the inline style is also !important.

    If you’ve got a rule like this…
    ul { display: block !important }
    …and some HTML like…
    <ul style="display: inline">...</ul>

    That list isn’t going to be inline, and it still won’t be inline even after using script to set element.style.display = "block";

    But, if you’re really stubborn, you can counter-strike with !important in script too:
    element.style.display = "block !important";

    Now, Robert’s getStyle doesn’t have that issue. Let’s assume that’s by design…

  • Tobie Langel
    April 26th, 2006 at 11:15

    An other interesting thing is that Firefox, Opera and Safari will returned the actual pixels of a font size applied with em, while IE only return the value in em.

    That is one of the most annoying differences between Gecko based browsers and Internet Explorer; it is of course related to the getComputedStyle and currentStyle functions which don’t render the same thing at all. (As their names rightly suggest, getComputedStyle returns the styles as computed for display, while currentStyle returns the result of the cascade, before computation into pixels.)

    I don’t think one function is better than the other. Actually, I would dream of having both of them available in either browser.

    For now, there is unfortunately no middle-ground (i.e. no getComputedStyle equivalent in IE, and no currentStyle equivalent in Firefox).

    So that’s tough luck if you need a cross-browser solution on issues like font-sizes set in anything else than pixels…

  • Robert Nyman - author
    April 26th, 2006 at 16:23

    Mislav,

    I’m not sure what’s in the Prototype library or how it works, but this is offerred just as a handy function and not a library replacement.

    Ash,

    Thanks for clearing that up.

    Tobie,

    Actually, I would dream of having both of them available in either browser.

    Me too… :-)

  • Sammy
    April 27th, 2006 at 17:02

    Could this function be adapted to be a bookmarklet ? Something like: click bookmarklet to see which elements are floated, and which are positioned (by giving them a border or something). It would be great to quickly analyze existing websites and their layout techniques. Giving a border to tables or divs with a bookmarklet is one thing, but instantly seeing the kind of positioning that is used would be really cool. Any ideas ?

  • Robert Nyman - author
    April 27th, 2006 at 21:31

    Sammy,

    I guess that could be done, but for such usage tools like the Web Developer Toolbar extension for Firefox is much better.

  • setmajer
    May 18th, 2006 at 7:12

    I’m very late to the party here, but one could make this script work in IE5 by replacing the regex with:

    while(-1 != (dashIndex = strCssRule.indexOf('-'))) {
    strCssRule= strCssRule.substring(0,dashIndex) + strCssRule.substring(dashIndex + 1, dashIndex + 2).toUpperCase() + strCssRule.substring(dashIndex + 2);
    }

    Also, it is possible to calculate the pixel height of text by adding a dummy element with a single character inside to the desired location in the document, zeroing padding and borders, setting line-height to 1 and then getting the offsetHeight.

    I suspect one could write an ugly little kludge that would use that technique to normalise returned font sizes (or even line-heights) to pixels.

    Getting pixel values for borders, padding and so on would be considerably trickier, however.

  • Inge Jørgensen
    June 7th, 2006 at 14:34
  • Ess
    July 15th, 2006 at 15:29

    Thanks a lot for sharing this useful tip with us.

  • Juan
    July 28th, 2006 at 16:09

    Do you know how to actually calculate the pixel width of a style in IE for this example? If I don’t set a ‘width’ on an object, FireFox and Safari return the proper pixel width, but IE returns ‘auto’. Any way around it? Thanks!

  • Robert Nyman - author
    July 29th, 2006 at 13:35

    setmajer,

    Thanks for the suggestions. And yes, dummy elements are always good to test things like that.

    Inge,

    Thank you for the added functionality.

    Ess,

    No problem! :-)

    Juan,

    To begin with, the idea is only to find out the rendered value when some CSS is actually applied. However, to make that work in IE, you then need to check for the element’s offsetWidth, like this:

    var intWidth = document.getElementById("juans-element").offsetWidth.

  • EJ - The only JavaScript library you’ll ever need - Robert’s talk
    November 7th, 2006 at 12:25

    […] A very handy way to find out the rendered CSS styles on an element, Described in detail in Get the rendered style of an element. Support for Array.push in I […]

  • aw’s blog 姿态永恒 » IEå’ŒFF的两种”姿态”
    February 14th, 2007 at 14:24

    […] F、IE、Opera、Safari下同时兼容的做法步骤: 1、定义函数getStyle - 参考 […]

  • Jonathan Leech
    March 22nd, 2007 at 21:47

    What would be even more awesome is if this supported the CSS shorthand properties; e.g. for border. It would be very convenient to be able to just call getStyle(elem, “border”) and it would return “2px solid green” or whatever. Instead you’ve got to call getStyle() on {border-left-, border-top-, border-right-, border-bottom-} * {color, style, width}. Even if it wasn’t smart and didn’t build the most efficient shorthand it would be very useful.

  • Robert Nyman - author
    March 23rd, 2007 at 8:58

    Jonathan,

    I agree that that would be good. As it is now, it just returns what the web browsers give you. However, it wpuld be a nice way to extend it, although it won’t be done just at this moment… :-)

  • Olle Lundberg
    July 17th, 2007 at 21:24

    Webkit has a bug in the way it handles the string passed to getPropertyValue() according to the spec the string passed, is case insenstive. I.e width==Width.

    I have created at test case and reported it to webkit.

    A workaround for now is making the strCssRule lowercase.


    function getStyle(oElm, strCssRule){
    var strValue = "";
    strCssRule=strCssRule.toLowerCase();
    if(document.defaultView && document.defaultView.getComputedStyle){
    strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
    }
    else if(oElm.currentStyle){
    strCssRule = strCssRule.replace(/-(w)/g, function (strMatch, p1){
    return p1.toUpperCase();
    });
    strValue = oElm.currentStyle[strCssRule];
    }
    return strValue;
    }

  • Bernie
    August 20th, 2007 at 17:28

    This function doesn’t work in Firefox with “backgroundImage”.

  • elektronaut » Blog Archive » Getting computed styles in Javascript
    September 6th, 2007 at 2:42

    […] computed styles in Javascript Robert Nyman has written a useful blog entry on this, you might want to read it as well. The getStyle() function is based on his, with one […]

  • Bereczki Andrei
    October 29th, 2007 at 11:03

    Hi, nice script, i was using something similar but this seems more browser friendly. I have a suggestion and 1 bug for you to fix (if you want of course):

    1. Stripping away the ‘px’ from the return values would be nice to be able to use it in mathematical operation
    i did it the following way:

    if(strValue.indexOf(”px”) != -1){ //stripping away ‘px’
    strValue = parseInt( strValue.slice(0, strValue.indexOf(”px”)) );
    }
    return strValue;

    2. There seems to be a bug with getting the border values. Even if the border is not set in CSS, i still get a 0px (medium in IE) and #000000 color for that border … is this normal?

    Have a great day! :-)

  • Bereczki Andrei
    October 29th, 2007 at 11:05

    o, forgot to mention, if i set the color property in CSS, the border color changes to that color, even if not set … annoying

  • Robert Nyman - author
    October 29th, 2007 at 13:54

    Olle,

    Thanks for the info!

    Bernie,

    You need to send in background-image to the function, like in CSS. Alternatively, you can send in just background

    Andrei,

    Thank you!
    1. It’s a good suggestion, but it was a deliberate choice to have it return the unit as well, in case there are more than one unit in use.
    2. The problem is that what is returned is the default value in the web browser, which can differ quite a lot between different web browsers.

  • iain
    November 7th, 2007 at 2:11

    Thanks for this… exactly what I needed.

    You absolute legend

  • Robert Nyman - author
    November 7th, 2007 at 10:47

    iain,

    I’m glad it helped! :-)

  • mihai copae
    April 22nd, 2008 at 15:56

    If you want to parse the entire CSS for document u can use this:

    n=document.styleSheets[0].cssRules.length
    css_rules=document.styleSheets[0].cssRules

    i=0;
    while(i<n){
    console.log(css_rules[i].cssText)
    i++;
    }

Share your thoughts:

HTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong> . If you want to display code examples, please remember to write &lt; for < and &gt; for >.

Comment preview

All the proceeds from ad clicks will go to charity. However, if you like to give something directly to charity yourself, I recommend choosing from the listed ones below.

  • Save the Children
  • Red Cross
  • Cancer Research UK
  • WWF

Top results