Get a CSS value with JavaScript
Asked Answered
B

8

270

I know I can set a CSS value through JavaScript such as:

document.getElementById('image_1').style.top = '100px';

But, can I get a current specific style value? I've read where I can get the entire style for the element, but I don't want to have to parse the whole string if I don't have to.

Bathetic answered 14/6, 2011 at 1:37 Comment(4)
What 'specific style value' are you trying to obtain?Monroe
current positioning values: height, width, top, margin, etc.Bathetic
Your question lends to believe you want something like var top = document.getElementById('image_1').style.top; May want to rephrase it if that's not what you wantElise
Thx All, both methods work perfectly, just what I needed. The Jquery method is a bit more compact, so I'll probably use that.Bathetic
C
453

You can use getComputedStyle().

var element = document.getElementById('image_1'),
    style = window.getComputedStyle(element),
    top = style.getPropertyValue('top');
console.log(top);
<img id="image_1">

jsFiddle.

Colemancolemanite answered 14/6, 2011 at 1:40 Comment(15)
If you want to change background color of a div for example, be careful to NOT USE "backgroundColor" instead of "backgroung-color" ;)Prepositive
This is a slw functionIntimist
Is slw an acronym or did you mean slow?Involutional
getComputedStyle is not supported in IE 8 and below.Involutional
Somewhat off topic: some (all?) shorthand css properties are not accessible in JavaScript. E.g. you can get padding-left but not padding. JSFiddleInvolutional
@DavidWiniecki i dont really believe webdevs should still consider IE8 a mainstream browser. considering it is no longer supported by microsoftMaid
Yes that's good news! (Btw that happened 3 months after my last comment: blogs.msdn.com/b/ie/archive/2014/08/07/…)Involutional
The people who use IE8 or below ... they should keep this in mind that Devs don't care about them now!!! I mean see its 2015 now , Use chrome or Fire of foxCienfuegos
@NickySmits, it's actually faster than JQuery's .css function. See benchmarks jsperf.com/getcomputedstyle-vs-style-vs-css/2 and jsperf.com/jquery-css-vs-getcomputedstyle/2Rahm
It ought to be faster, jQuery uses these methods to get the values.Colemancolemanite
Is there a difference between style.getPropertyValue('top') and style.top?Sikora
@Sikora Is the 'getPropertyValue' method required for retrieving CSS?Slant
The problem here is that it returns a string value. What if we want to have the actual integer number?Concepcion
What if this element still not added to DOM? Then this approach does not work.Floatplane
Why do the first two lines end with a comma?Katharyn
A
26

The element.style property lets you know only the CSS properties that were defined as inline in that element (programmatically, or defined in the style attribute of the element), you should get the computed style.

Is not so easy to do it in a cross-browser way, IE has its own way, through the element.currentStyle property, and the DOM Level 2 standard way, implemented by other browsers is through the document.defaultView.getComputedStyle method.

The two ways have differences, for example, the IE element.currentStyle property expect that you access the CSS property names composed of two or more words in camelCase (e.g. maxHeight, fontSize, backgroundColor, etc), the standard way expects the properties with the words separated with dashes (e.g. max-height, font-size, background-color, etc). ......

function getStyle(el, styleProp) {
    var value, defaultView = (el.ownerDocument || document).defaultView;
    // W3C standard way:
    if (defaultView && defaultView.getComputedStyle) {
        // sanitize property name to css notation
        // (hyphen separated words eg. font-Size)
        styleProp = styleProp.replace(/([A-Z])/g, "-$1").toLowerCase();
        return defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
    } else if (el.currentStyle) { // IE
        // sanitize property name to camelCase
        styleProp = styleProp.replace(/\-(\w)/g, function(str, letter) {
            return letter.toUpperCase();
        });
        value = el.currentStyle[styleProp];
        // convert other units to pixels on IE
        if (/^\d+(em|pt|%|ex)?$/i.test(value)) { 
            return (function(value) {
                var oldLeft = el.style.left, oldRsLeft = el.runtimeStyle.left;
                el.runtimeStyle.left = el.currentStyle.left;
                el.style.left = value || 0;
                value = el.style.pixelLeft + "px";
                el.style.left = oldLeft;
                el.runtimeStyle.left = oldRsLeft;
                return value;
            })(value);
        }
        return value;
    }
}

Main reference stackoverflow

Apodosis answered 19/4, 2013 at 20:11 Comment(0)
A
23

Use the following. It helped me.

document.getElementById('image_1').offsetTop

See also Get Styles.

Ardoin answered 9/8, 2011 at 9:22 Comment(0)
R
21

Cross-browser solution to checking CSS values without DOM manipulation:

function get_style_rule_value(selector, style)
{
 for (var i = 0; i < document.styleSheets.length; i++)
 {
  var mysheet = document.styleSheets[i];
  var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;

  for (var j = 0; j < myrules.length; j++)
  {
   if (myrules[j].selectorText && myrules[j].selectorText.toLowerCase() === selector)
   {
    return myrules[j].style[style];
   }
  }
 }
};

Usage:

get_style_rule_value('.chart-color', 'backgroundColor')

Sanitized version (forces selector input to lowercase, and allows for use case without leading ".")

function get_style_rule_value(selector, style)
{
 var selector_compare=selector.toLowerCase();
 var selector_compare2= selector_compare.substr(0,1)==='.' ?  selector_compare.substr(1) : '.'+selector_compare;

 for (var i = 0; i < document.styleSheets.length; i++)
 {
  var mysheet = document.styleSheets[i];
  var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;

  for (var j = 0; j < myrules.length; j++)
  {
    if (myrules[j].selectorText)
    {
     var check = myrules[j].selectorText.toLowerCase();
     switch (check)
     {
      case selector_compare  :
      case selector_compare2 : return myrules[j].style[style];
     }
    }
   }
  }
 }
Rigsby answered 9/10, 2014 at 7:29 Comment(2)
I was having a long day and this wasn't working for a number of reasons. pastie.org/9754599 works a lot better by throwing out invalid rule lists and lowercasing both sides of the final ===. Many thanks your solution still saved the day!Pants
good answer, added a sanitised version at the end to fix a few edge case use issues.Brownfield
H
11

In 2021

check before use

You can use computedStyleMap()

The answer is valid but sometimes you need to check what unit it returns, you can get that without any slice() or substring() string.

var element = document.querySelector('.js-header-rep');
element.computedStyleMap().get('padding-left');

var element = document.querySelector('.jsCSS');
var con = element.computedStyleMap().get('padding-left');
console.log(con);
.jsCSS {
  width: 10rem;
  height: 10rem;
  background-color: skyblue;
  padding-left: 10px;
}
<div class="jsCSS"></div>
Headsail answered 26/11, 2019 at 11:17 Comment(3)
Safari says "TypeError: element.computedStyleMap is not a function". :-(Klansman
Safari had no support till now :-(Headsail
Not supported on FireFox (currently 111.0)Stalinist
M
7

If you set it programmatically you can just call it like a variable (i.e. document.getElementById('image_1').style.top). Otherwise, you can always use jQuery:

<html>
    <body>
        <div id="test" style="height: 100px;">Test</div>
        <script type="text/javascript" src="jquery.min.js"></script>
        <script type="text/javascript">
            alert($("#test").css("height"));
        </script>
    </body>
</html>
Mcdermott answered 14/6, 2011 at 1:50 Comment(2)
I don't think your jQuery example is very clear (or correct).Colemancolemanite
style property return all style inline apply to element, not defined by css rules.Pennsylvania
M
0

As a matter of safety, you may wish to check that the element exists before you attempt to read from it. If it doesn't exist, your code will throw an exception, which will stop execution on the rest of your JavaScript and potentially display an error message to the user -- not good. You want to be able to fail gracefully.

var height, width, top, margin, item;
item = document.getElementById( "image_1" );
if( item ) {
  height = item.style.height;
  width = item.style.width;
  top = item.style.top;
  margin = item.style.margin;
} else {
  // Fail gracefully here
}
Monroe answered 14/6, 2011 at 1:56 Comment(4)
That is a bad idea, unless you really expect that the node may not be in the DOM. Blind null checks when a null is not expected may give you the appearance of no errors, but it's more likely hiding a bug. If you expect the node to be there, do not code for it not being there, let an error occur so you can fix your code. This answer has nothing to do with the question itself and since it's more of a (bad) suggestion, it should be a comment.Sining
Thanks for your comment. I do that because I tend to develop defensively. Here's the question: how would you see the error on the user's machine? Remember, what works for you on your machine may not work for others (different browsers & OSs, plugins that affect page behavior, various other things turned off, etc). The point was to have it fail gracefully so the page still did something close to what was intended instead of popping up a useless error to the user.Monroe
@Monroe There' a browser bug where it doesn't render an element with an id of "image_1"? ;)Colemancolemanite
@Colemancolemanite No. If there is no element with that id, then the OP's code will fail with an error. Example. My suggestion was to code so this can never happen.Monroe
P
0

The cross-browser solution without DOM manipulation given above does not work because it gives the first matching rule, not the last. The last matching rule is the one which applies. Here is a working version:

function getStyleRuleValue(style, selector) {
  let value = null;
  for (let i = 0; i < document.styleSheets.length; i++) {
    const mysheet = document.styleSheets[i];
    const myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
    for (let j = 0; j < myrules.length; j++) {
      if (myrules[j].selectorText && 
          myrules[j].selectorText.toLowerCase() === selector) {
        value =  myrules[j].style[style];
      }
    }
  }
  return value;
}  

However, this simple search will not work in case of complex selectors.

Polyphemus answered 16/5, 2017 at 17:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.