1

I need to get a computed CSS position for an element, but when using auto instead of a number value I get inconsistent results across browsers.

For example, in the demo below when setting bottom: auto; Chrome and Firefox reports auto, but Edge reports 0px

var el1 = document.querySelector('#one');
el1.innerText = getComputedStyle(el1).bottom;

var el2 = document.querySelector('#two');
el2.innerText = getComputedStyle(el2).bottom;
#one, #two {
  position: sticky;
  padding: 20px;
  color: white;
}

#one {
  bottom: 0px;
  background: red;
}

#two {
  bottom: auto;
  background: blue;
}
<div id="one"></div>
<div id="two"></div>

Is there some other way to get the actual computed value of auto consistently across browsers?


In the Edge inspector you can see (screenshot below) the actual set value is auto but it shows the computed value as 0px

Edge Computer Styles


Screenshots

Chrome 74.0.3729.131

Chrome

Edge 44.17763.1.0 | EdgeHTML 18.17763

Edge

Chris Barr
  • 29,851
  • 23
  • 95
  • 135
  • 1
    can't reproduce this. it shows the same for me in both inspectors. could this be some angular magic (because i see ngcontent there) – malifa May 14 '19 at 15:30
  • Really? Running the demo in this question in Chrome produces `auto` and in Edge produces `0px` - for the blue box. You get something different? – Chris Barr May 14 '19 at 15:40
  • Yea really, i get the same output running your code snippet here in edge and chrome. i also tried it locally and via codepen. no difference for me. Browser version maybe? – malifa May 14 '19 at 15:42
  • Weird... I've added screenshots from each now to show that I'm not crazy. – Chris Barr May 14 '19 at 17:29
  • To be fair, the consistency has nothing to do with `getComputedStyle()` specifically, but what the default styles are for each vendor. By the way, this outputs `auto` for me in both Chrome and Edge. – Patrick Roberts May 14 '19 at 17:32
  • 1
    Windows 10, Microsoft Edge 44.17763.1.0 (Microsoft EdgeHTML 18.17763) shows `0px 0px` for me (And `0px auto` in Chrome) – Roko C. Buljan May 14 '19 at 17:37
  • Is there a reason [getClientBoundingRect](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) or related API wouldn't work for what you're doing? – ray May 14 '19 at 17:45
  • @rayhatfield yes, because I want to know what the applied/computed styles curretly say, I don't care about where it actually is on the page. I'm purposefully setting the bottom to be `auto` so it doesn't have a specific value in this case. I want it to be automatic. – Chris Barr May 14 '19 at 17:52

2 Answers2

1

There have been recent changes in this area.

Previously, getComputedStyle was returning the Computed Values of an element, now it should return its Resolved Values.

For the bottom property the rules to get this resolved value are:

A resolved value special case property like top defined in another specification
  If the property applies to a positioned element and the resolved value of the display property is not 'none' or 'contents', and the property is not over-constrained, then the resolved value is the used value. Otherwise the resolved value is the computed value.

It sounds like your browser treats your elements as a positioned element and thus uses the used value (0px) instead of the computed value (the keyword 'auto' or a computed <length-percentage> value).

I must admit I'm not quite clear as to why all the other browsers don't consider your sticky elements as positioned elements, I would have thought they were also, but they do agree that a relatively positioned element returns the resolve value '0px',

var el1 = document.querySelector('#one');
el1.innerText = getComputedStyle(el1).bottom;

var el2 = document.querySelector('#two');
el2.innerText = getComputedStyle(el2).bottom; // '0px' everywhere
#one, #two {
  position: relative;
  padding: 20px;
  color: white;
}

#one {
  bottom: 0px;
  background: red;
}

#two {
  bottom: auto;
  background: blue;
}
<div id="one"></div>
<div id="two"></div>

While a non-positioned one returns the computed-value 'auto'.

var el1 = document.querySelector('#one');
el1.innerText = getComputedStyle(el1).bottom;

var el2 = document.querySelector('#two');
el2.innerText = getComputedStyle(el2).bottom; // 'auto' everywhere
#one, #two {
  position: static;
  padding: 20px;
  color: white;
}

#one {
  bottom: 0px;
  background: red;
}

#two {
  bottom: auto;
  background: blue;
}
<div id="one"></div>
<div id="two"></div>

Unfortunately, I don't think there is a way to get consistent values across browsers that did implement these changes, the ones that didn't, and Edge, unless if you can avoid positioning your elements, then you should get 'auto' everywhere.

Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • Great info - thanks! For my use case in a jasmine test it was just annoying to check that the `bottom` value was what I expected in certain conditions, but running the tests in Edge made them fail. I was able to modify my text to expect either value so they pass now. – Chris Barr May 16 '19 at 12:22
0

I've tried your code and reprodcued your issue on my side.

You could check from MDN and Can I Use that getComputedStyle() is normally supported by most modern browsers.

From my point of view, the different result of bottom value may be the browsers' self behaviour to show the bottom attribute.

Chrome read the bottom as auto but Edge read it as 0.

I've also test that if I set the width as auto, the result will be the same.

    #two {
        bottom: auto;
        background: blue;
        width:auto;
    }

el2.innerText = getComputedStyle(el2).width;

enter image description here

Jenifer Jiang
  • 371
  • 1
  • 9