3

The values returned by getComputedStyle are resolved values. These are usually the same as CSS 2.1’s computed values, but for some older properties like width, height, or padding, they are instead the same as used values.

-- MDN: window.getComputedStyle() notes

So is it currently possible to get the resolved value of height as it was specified in stylesheet?

I.e. know that some element's computed ..px (= used) height was specified as height: 100%; in style sheet? (100% being the resolved value in question.)

Is there some new specification regarding this problem in consideration?


Edit 2020-08-17: see very similar question and excellent answer from 2012: Is there a cross-browser method of getting the used css values of all properties of all elements? (Sadly, noting seem to ave changed since then.)

myf
  • 6,206
  • 1
  • 30
  • 37
  • To clarify, you're looking to determine the pixel height of an element that has been assigned a percentage value for `height`, correct? – IronFlare Aug 16 '19 at 15:57
  • Check out: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight – Jon Koops Aug 16 '19 at 16:01
  • No, pixel value (used) is that in the `getComputedStyle(el).height`. What I need is to get literally '`100%`' if the style sheet rule contained `height: 100%;`, or '`12vh`' if it contained `height: 12vh;`. – myf Aug 16 '19 at 16:02
  • Oh, interesting. I believe only way to do *that* would be to manually divide the pixel height by the parentElement, window, or viewport height. I don't think there's a way to get the percentage value back, but I'll check and update. – IronFlare Aug 16 '19 at 16:04

2 Answers2

2

No, there is no specification or functionality that supports or enables this method. There are plenty of ways to go the other direction, including...

... but none that will retrieve the exact percentage specified in the CSS, unfortunately.

You can try, as I've done below.


RegEx

If your height is specified as an inline style, you could RegEx it out of the attribute like so1:

let elem = document.getElementsByTagName("div")[0];
let re = /(?<=\height:\s+?)[^\;]+/i;
console.log(re.exec(elem.getAttribute("style"))[0]);
<div style="color: black; height: 100%; background: white;"></div>

This is terrible practice, though, and could be janky if there are multiple width declarations (which should never happen, but we're already in "bad code land", so why not?). Of course, this ignores the fact that inline styles should generally be avoided in the first place, so this probably won't apply to you.


Bounding calculations

It's also possible to calculate the value yourself by comparing the height of the element with the height of its parent.

let elem = document.getElementById("inner");
let pare = elem.parentElement;

let hrat = `${100*(elem.offsetHeight / pare.offsetHeight)}%`;

console.log(hrat);
#container {
  height: 300px;
  width: 400px;
  background: repeating-linear-gradient(45deg, rgba(255,0,0,0.35), rgba(255,0,0,0.35) 10px, rgba(255,0,0,0.1) 10px, rgba(255,0,0,0.1) 20px), linear-gradient(white, white);
}

#inner {
  height: 200px;
  width: 400px;
  background: darkgreen;
  mix-blend-mode: hue;
}
<div id="container">
  <div id="inner"></div>
</div>

If you add borders, margin, or padding, or the element adapts to the size of its content, though, this calculation will be incorrect.


Conclusion

In conclusion, everything is jank.

In my opinion, you'd be better off not fighting with CSS and JavaScript to coerce the value from the available information, and working out a way to do without the value. I've tried to do this kind of thing many times, so be forewarned: this way lies madness.


1RegEx lookbehinds are not even remotely close to being fully supported, so shouldn't be used in production.

Community
  • 1
  • 1
IronFlare
  • 2,227
  • 2
  • 17
  • 26
  • Thanks for ideas hints. I probably shouldn't have used `100` example in the question because it could lead to conclusion I'm looking for way of telling something matches other dimension. What I am actually aiming for is more precisely the '%' / 'vw' / any other units specified part. And also for any source of style, not just inline attribute. – myf Aug 16 '19 at 17:15
  • Presumably it could be extracted from styleSheets using ~ https://stackoverflow.com/questions/42025329/ but as I understand it then one would have to write own specificity calculator to get rule that is really in effect. (Presumably that 'madness' you were reffering to :]) – myf Aug 16 '19 at 17:20
  • I can say with certainty that it's not possible to determine programmatically for any given unit. You could try to read the `textContent` of ` – IronFlare Aug 16 '19 at 17:20
  • I wasn't even aware of the `document.styleSheets` property, but it looks like its interfaces are very similar to that of `Node` (namely `nodeType` and its all-caps constants). Madness. – IronFlare Aug 16 '19 at 17:24
1

You could read the stylesheet rule itself. If you know the selector that sets an elements width/height you can do this:

.box {
  width: 12vw;
  background: red;  
}
<div class="box">red</div>
var sheet = document.styleSheets[0];
var rules = sheet.rules;

for (var i = 0; i < rules.length; i++) {
  if (rules[i].selectorText == '.box') {
    console.log(rules[i].style.width);
  }  
}

This will give you the 12vw you're looking for.

Depending on how your elements are defined, you could in theory create a helper function that gets these values for you by looping through the elements classList.

Zevan
  • 9,541
  • 3
  • 29
  • 47