Get element CSS property (width/height) value as it was set (in percent/em/px/etc)
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 div
s:
div 1: 100px
div 2: 50%
div 3: auto
div 4: 44em
(At jsFiddle)
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>
Apparently there is no DOM API for this
https://developer.mozilla.org/en/DOM/window.getComputedStyle#Notes
EDIT: oops, just realized this was marked for Google Chrome
Try window.getMatchedCSSRules()