I have two absolutely positioned divs that I have lined up to look like an "L" or a kinked pipe. On Chrome at 100% zoom on a MacBook Pro (16-inch, 2019), it looks like this:
The issue is that as I adjust the browser zoom level, the two divs go in and out of alignment by one pixel. For example, this is what it looks like at 90% zoom:
And the same thing happens at 110% zoom. If I adjust the position by 1px
, it goes back into alignment. What causes this, and is there a way to prevent it all zoom levels?
Here is a working example on codepen: https://codepen.io/elethan/pen/gOLQXrB
CSS:
#outer-container {
width: 200px;
height: 40px;
background: gray;
padding: 10px;
position: absolute;
top: 50%;
right: 50%;
}
#progress-bar {
background: purple;
height: 40px;
width: 80%;
border: 4px solid gray
}
#down {
background: purple;
height: 40px;
width: 40px;
border: 10px solid gray;
border-top: 0 solid transparent;
position: absolute;
left: 124px;
top: 54px;
}
HTML:
<div id="outer-container">
<div id="progress-bar"></div>
<div id="down"></div>
</div>
It happens due to the poor accuracy when dealing with floating point numbers in browsers.
The worst part is that they round differently the rendered element (what we actually see) from the element's size or positioning (the size they occupy or are placed at).
That's why some elements seems to be +/- 1 pixel from the position they should be. It can vary depending on the rendering engine and even the size of your window, as you can try, it seems to fix/break each pixel you resize.
In Firefox at 90% zoom:
padding
of outer-container
from 10px
renders 9 (it's fine).border
of progress-bar
from 4px
renders 3 (rounds down from 3.6)content
of progress-bar
from 40px
renders 36 (it's fine).top
position of down
from 54px
, renders at 49 (rounds up from 48.6).In this case, the problem seems to be the rounding up for the down
's position top
, and rounding down the border
's width of progress-bar
. That's the empty pixel between progress-bar
and down
boxes.
That's just an example of a couple of elements in a single browser, as you can imagine, it will happen all the time with each element in the screen for each browser.