Chris Barr
Chris Barr

Reputation: 33972

getComputedStyle() consistency across browsers

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

Upvotes: 1

Views: 462

Answers (2)

Kaiido
Kaiido

Reputation: 136598

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.

Upvotes: 1

Jenifer Jiang
Jenifer Jiang

Reputation: 381

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

Upvotes: 0

Related Questions