Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get element CSS property (width/height) value as it was set (in percent/em/px/etc)

How could one get an elements CSS property (for example width/height) as it was set with CSS rules, in whatever units it was set (eg percent/em/px)? (In Google Chrome, preferably frameworkless).

Using getComputedStyle returns the current value in pixels, so does css() in jQuery.

For example:

<div class="b">first</div> <div id="a" class="a">second</div>  <style>      div      { width: 100px; }      x, div#a { width: 50%;   }      .a       { width: 75%;   } </style> 

While iterating all div elements in this example, I'd like to be able to get the second divs width as 50% (and the first as 100px).


Chrome element inspector can display CSS property value as they were set, so it should be possible in Chrome.

Chrome element inspector showing property value as they were set


Not an exact duplicate of the linked question, as there the accepted answer there is a simple hack that produces a percentage width no matter what kind of width is set. And for the rest you have to know the selector used to make the active rule? How would one know that?

like image 674
Qtax Avatar asked Mar 16 '12 01:03

Qtax


People also ask

When you set the width and height properties of an element with CSS?

The height and width properties are used to set the height and width of an element. The height and width properties do not include padding, borders, or margins. It sets the height/width of the area inside the padding, border, and margin of the element.

What CSS property is used for setting the width of an element?

The width CSS property sets an element's width. By default, it sets the width of the content area, but if box-sizing is set to border-box , it sets the width of the border area.

What CSS property is used for setting the height of an element?

The height CSS property specifies the height of an element. By default, the property defines the height of the content area. If box-sizing is set to border-box , however, it instead determines the height of the border area.

How do you find the height and width in CSS?

The CSS height and width property are used to specify the height and width of an element respectively. We can also set the maximum and minimum values for these properties using the max-height, max-width, min-height, and min-width properties.


2 Answers

It's not as simple as just calling WebKits getMatchedCSSRules(), it does return the matched rules in order of priority (altho I've seen no mention of this order in the docs), but the order does not take regard to property important priority and does not include element styles. So I ended up with this function:

getMatchedStyle

function getMatchedStyle(elem, property){     // element property has highest priority     var val = elem.style.getPropertyValue(property);      // if it's important, we are done     if(elem.style.getPropertyPriority(property))         return val;      // get matched rules     var rules = getMatchedCSSRules(elem);      // iterate the rules backwards     // rules are ordered by priority, highest last     for(var i = rules.length; i --> 0;){         var r = rules[i];          var important = r.style.getPropertyPriority(property);          // if set, only reset if important         if(val == null || important){             val = r.style.getPropertyValue(property);              // done if important             if(important)                 break;         }     }      return val; } 

Example

Given the following code and style rules:

<div class="b">div 1</div> <div id="a" class="a d2">div 2</div> <div id="b" class="b d3" style="width: 333px;">div 3</div> <div id="c" class="c d4" style="width: 44em;">div 4</div>  <style> div      { width: 100px; } .d3      { width: auto !important; } div#b    { width: 80%;   } div#c.c  { width: 444px; } x, div.a { width: 50%;   } .a       { width: 75%;   } </style> 

this JS code

var d = document.querySelectorAll('div');  for(var i = 0; i < d.length; ++i){     console.log("div " + (i+1) + ":  " + getMatchedStyle(d[i], 'width')); } 

gives the following widths for the divs:

div 1:  100px div 2:  50% div 3:  auto div 4:  44em 

(At jsFiddle)

like image 90
Qtax Avatar answered Oct 09 '22 13:10

Qtax


Good news everyone! There seems to be a CSS Typed OM on his way in the w3c drafts.

Fast reading this document, it seems that the goal of this maybe to-be specification, is to ease the access of CSSOM values from javascript.

The really important part of this for us here is that we will have a CSSUnitValue API, which will be able to parse CSS values to an object of the form

{   value: 100,   unit: "percent", // | "px" | "em" ...   type: "percent"  // | "length" } 

And add a computedStyleMap() method, to the Element interface, from which we will be able to get the values actually applied on our elements.

As of today, only Chrome implements it (since 66).

(() => {    if (!Element.prototype.computedStyleMap) {      console.error("Your browser doesn't support CSS Typed OM");      return;    }    document.querySelectorAll('.test')      .forEach((elem) => {        let styleMap = elem.computedStyleMap();        const unitvalue = styleMap.get('width');        console.log(elem, {          type: unitvalue.type(),          unit: unitvalue.unit,          value: unitvalue.value        });      });    /* outputs      <div class="b test">first</div> {      "type": {        "length": 1      },      "unit": "px",      "value": 100    }        <div id="a" class="a test">second</div> {      "type": {        "percent": 1      },      "unit": "percent",      "value": 50    }    */    })();
div.test {  width: 100px; }  x,div#a {  width: 50%; }  .a {  width: 75%; }
<div class="b test">first</div>  <div id="a" class="a test">second</div>
like image 25
Kaiido Avatar answered Oct 09 '22 12:10

Kaiido