Forum Moderators: not2easy
<style>
body {
font-size: 1em;
padding: 8em 2em 2em 8em;
margin: 0;
background: #000;
}
#container {
width: 20em;
height: 200px;
background: #fff;
}
#box {
position: absolute;
left: 2em;
width: 6em;
height: 4em;
background: #fff;
}
</style>
<body>
<div id="container">
<div id="box"></div>
</div>
</body>
What you should see is a large white rectangle, with a small white rectangle flush along the left edge. It works as expected in Firefox and IE, but any WebKit based browsers -- tested in Chrome and Safari -- render a 1px gap between the two rectangles. This is caused by WebKit interpreting the "left: 2em;" on the smaller rectangle as 25px, while the other renderers interpret it as 26px.
There's a quick and easy solution -- drop the 0.8 font size in the body, and everything is fine in both browsers. And admittedly, it was stupid of me to declare the font size in the body. But it's still a little unnerving that WebKit is messing up the calculation.
Has anyone ever noticed this before? Am I going insane, or is this really a bug in the WebKit renderer?
Update: Here's a similar test case, showing the error twice side-by-side. Take a look at the code, think about what the result should look like, and then join my frustration.
<style>
body {
font-size: 0.8em;
padding: 8em;
margin: 0;
background: #000;
}
#middle {
width: 6em;
height: 6em;
background: #ccc;
}
#left {
position: absolute;
left: 14em;
width: 6em;
height: 6em;
background: #999;
}
#right {
position: absolute;
left: 2em;
width: 6em;
height: 6em;
background: #fff;
}
</style>
<body>
<div id="right"></div>
<div id="left"></div>
<div id="middle"></div>
</body>
You just need to allow for those rounding errors.
Let's assume an em starts out as 12px (or whatever, it doesn;t matter all that much)
you then multiply it with 0.8: resulting in 9.6px.
now 8em is 76.8 px. But your browser will have to round it all before rendering it. (let's assume it chooses 10px for the font and 77px for this) but that means that 10px*8 doesn't fit in 77 px!
It's just rounding errors, and there is nothign a browser can do.
You on the other hand can help minimize it:
- avoid creating fractions that then need to be multiplied
- always calculate things in the same direction from the same side, keepign your origin in one spot and not adding up dimensions (but the browser might do things differently internally when calculating e.g. auto margins, so still be prepared for a pixel off)
For the rest: make sure you dont need "pixel perfect", it won't happen.
Let's give you another example:
- you center a block of 7 pixels in a box 20pixels wide
- the margins are (20-7)/2 =6.5 px, but we need to draw the block in whole pixels, so we can choose left or right where we add half a pixel and the other we loose that half a pixel.
- we now add a 2 more boxes equal size on both sides trying to fill up the margins fully but not overlapping: there's either going to be an overlap on one side of the centered block or there's going to be a gap on the other side, no matter what size we use, no matter what the browser chose earlier.
The one way out for a browser would be to draw the box on half pixels and use anti-aliasing, but that's such a can of worms in itself that it's best for all if they stick to whole pixels for now and we just learn to take rounding errors into account.