Fig. 4: Composition
img 40*243
element A
element B
element C
element D
element E
element F
element G
Fig. 1: Elements A-G and a static image 40x243px.
.element {
    background-color: #ddd;
    width: auto;
    border-top: 1px solid blue;
    padding-top: 3.25px;
    height: 32px;
    padding-bottom: 3.25px;
    border-bottom: 1px solid red;
    }
computed element box height = 40.5 px
(2*margin + 2*border + 2*padding + height)
element
Fig. 2: Single element with px-fixed real paddings
 
update
Most of the rounding errors shown on this page (Fig. 1, 3, 4) are fixed since Wrong space between block level elements that have no margin was fixed in the FF nightly build 2005-03-29. This is a huge progress. Thank you.
css-d: overlaps and gaps due to Geckos attempt to render exactly
While switching to <li>'s with elements like table rows, I stumbled into a lot of rounding problems. I needed a design with sizeable padding, so I chose font-size: 1em; padding: 0.5em; and a bottom-margin of 1px to show the parents background as a grid. But while zooming text-size in Mozilla, there were some ugly gaps between the 'rows'. The margins seemed to be wider. Sometimes, depending on the parameters, the margins collapsed and the elements stuck together.
Fiddling with the famous DOM Inspector tool, I noticed that Gecko calculates continually with floating point length values for exact positioning. These fractional values are due to calculations on the device-independent coordinate space.[1]
An em-padding, -margin, -height, -line-height or the use of centimetres or ex will definitely end in a fraction. To illustrate the consequences, I'll use px-fixed real paddings in this first example (Fig. 1-3).
 
IE6
The integer length value 40px is used to compute the position of the consecutive elements. 6*40px=240px. The element G will start at position: 240px+1px;
There are no overlaps and no gaps (Fig. 1).
But the overall height A-F is not exact due to the rounding.
And with a glance at the absolute positioned planes (Fig. 4) while zooming, you'll see IE too has rounding problems ... [2]
Gecko Overlap
The real 40.5px is used to compute the position of the consecutive elements. 6 * 40.5px = 243px. The element G will start at expected position: 243px + 1px; the height A-F is exact (Fig. 1).
The height of each element is rounded up to 41px for the viewport. This causes an overlapping (element C overlaps B by 1px, element E overlaps D ...), so the red border-bottom is covered by the blue border-top.
The internal origin of element B is computed to 1 + 40.5 = 41.5, rounded up to 42px for output. Element B is drawn with a height of 41px, with its red bottom-border in position 42 + 41 - 1=82. The internal origin of element C is computed by adding real height of 40.5 to the internal position of element B (41.5)= 82px. But that's the position of the red bottom-border of element B, its overlapped! [1]
Tab. 1: Fractional calculated pixel offsets and rendered offsets
element A B C D E F G
internal origin 1.0 41.5 82.0 122.5 163.0 203.5 244.0
screen px 1 42 82 123 163 204 244
distance to previous - 41 40 41 40 41 40
overlap previous - - + - + - +
Gecko Gaps
The opposite occurs when the padding is computed to 3.7px, i.e. There are gaps between the elements (Fig. 3).[3]
element A
element B
element C
element D
element E
element F
element G
Fig. 3: Rounding-up and gaps
 

"De Stijl"
Let us discuss the composition of coloured squares in the upper right corner (Fig. 4). Each square is absolute positioned, therefore rendered out of the text flow. The black one is for better contrast. The em-dimensions are listed in the table (Tab. 2).
If you zoom to different text-sizes, you will see the 1px gaps between the squares or the overlapping. The lime border is sometimes affected or the silver square shines through.
As Robert O'Callahan (a Mozilla engineer) pointed out, there are two different problems: "The first issue is about how to render a layout where some elements have been positioned at fractional pixel offsets. The second issue is about how to lay out elements when some measurements are given with fractional pixels."
There is a discussion at Bugzilla about these topics (Pixel roundoff problems and Fix the use of units in Gecko). See also [1], [2] and [3].
 
Tab. 2: Measures and absolute offsets of the squares in Fig. 4
color black (red border) silver (lime border) maroon navy blue black navy maroon
view
width/height (em) 12 10 5 5 2.5 2.5 2.5 2.5
abs. top (em) 0 0 0 5 2.5 5 0 7.5
abs. right (em) 0 0 5 0 2.5 5 7.5 0

Gecko Text Zooming
Geckos increasing/decreasing feature leads to rounding errors. Example: WinXP,
body {
 font-family: sans-serif;
 font-size: 10px;
 ...
 }

.element {
 height: 1em;
 padding:0.5em;
 ...
 }
In 150% Zoom, 2*padding is calculated to 15.06666, and in consequence there are occasionally overlaps. In 75% zoom, expected 0.5em padding should add to 7.5px + font-size 7.5px= 15px, but these fractions are computed to 14.93333: gaps again. And this just with a basis of 10px font-size.
 
Tab. 3: Differences between expected and calculated font-sizes. Data from the Dom Inspector tool may differ on your local system
Zoom 50% 75% 90% 100% 120% 150% 200%
expected font-size (px) 5.0 7.5 9.0 10.0 12.0 15.0 20.0
computed font-size (px) 5.0 7.46667 8.93333 10.0 12.0 15.0 20.0
computed 0.5em padding (px) 2.53333 3.73333 4.46667 5.0 6.0 7.53333 10.0

Built-in Rounding-Errors
By default (file: res/html.css; res/form.css), firefox 0.9 defines some html-tags with a em-length (padding/margin/height: p, dl, multicol, blockquote, h1-h6, listing, plaintext, xmp, pre, ol, hr, form, fieldset, option). Especially those with em-fractions (h1-h6, hr) will lead into gaps/overlaps (Fig. 5-6).
Notice while increasing/decreasing text-size: occasionally there are interferences due to gaps. (When I'm tired and squint-eyed, I can't concentrate upon the 1px-differing distances between the elements, so I had to give them a background image 10px20px.png -- like two net curtains on top of each other -- where interferences become visible to indicate gaps and overlaps.)
 
Example: res/html.css hr{... margin: 0.5em auto 0.5em auto; ...}


Fig. 5a: Two <hr>-tags {width: 75%}




















Fig. 5b: Twenty <hr>-tags {width: 75%} in a wrapper with a background-image
 
Example: res/html.css h5{... font-size: 0.83em; ... margin: 1.67em 0; ...}. to illustrate the gaps/overlaps, with its own 10px20px.png background-image.
h5
h5
Fig. 6a: Two <h5> with a background-image.
Note: If IE shows periodic effects every second <h5>: the background image has a even pixel-height, the <h5> has a odd pixel-height, depending on the text-size. This is no rounding-error.
h5
h5
h5
h5
h5
h5
h5
h5
h5
h5
h5
h5
h5
h5
h5
h5
h5
h5
h5
h5
Fig. 6b: Twenty <h5> in the wrapper
 

There is more than this ...
[1] In fact, this is more complicated (as if it wasn't before). Gecko's layout uses a 32-bit signed integer coordinate space for internal graphic representation, based on device-independent units of measure named TWIPs. TWIP means: 20th of a point. All graphic coordinates are calculated in TWIPs.
A good graphic engine like Gecko can render to diverse devices (i. e. Win screen 96dpi, Mac screen 72 dpi, my old-fashioned ink printer 300dpi ...). Fast zooming is possible due to the transformation of internal big coordinate space offsets to the device-pixels. The result will sometimes end in fractions of a CSS pixel, to be rounded (see W3C CSS 2.1 specs: Lengths for the difference between a device pixel and a CSS pixel).
1 inch = 72 point = 1440 TWIPs.
1 CSS pixel will be represented by an amount of TWIPs: 1440 / device_dpi = TWIPs per CSS pixel
Tab. 4: Factors of internal coordinate space and device coordinate space
Device dpi: 72 80 90 96 120 144
TWIPs per CSS pixel: 20 18 16 15 12 10
Example: A 0.5em length at 11pt font-size at 96dpi will end as a fractional pixel length: 0.5*11*20 = 110 TWIPs = 110/15= 7.3333 CSS pixel. One square will be rendered to rounded-off 7 pixel width. Two of them will cause a internal 220 TWIPs = 14.6666 offset for the third one -> rounded-up 15px. But 7px+7px aren't 15px, there will be a 1px gap behind them (or before the third, as you like it).
This is illustrated by the composition in the lower left corner (Fig. 7, fixed). Two lines of four squares are compared, both with a 11pt font-size (below and above are just single squares). The upper red squares have pixel-fixed dimensions (7.3333px = 220 TWIPS). The lower green squares have a 0.5em-width. As computed above for 96dpi, there is a gap after two red squares. And there is the same gap in the green line at 100% zoom. Then, the first two green and red squares are seamless floated, but the third will leave a gap, and the fourth will float seamless again.
This example is designed for a 96dpi screen resolution. With Mozilla on Linux, preferences/ appearance/ fonts/ display resolution takes effect (didn't get any effect under Windows XP until I forced XP to user defined resolution and reboot to get a blurred view): at 72dpi, I had to zoom to 150% to see a gap, Mac users might confirm to this. Why? Table 4 offers 20 TWIPs/pixel at 72dpi. Again: (0.5em * 11pt * 20th_of_a_point =) 110 TWIPS as a internal measure for one square's width, no change. But 110 TWIPs makes 110/20 device_dpi pixels = 5.5 pixel. And the zoom? Right, 5.5 pixel * 150% = 8.25 pixel. Ok, each square will have a length of (rounded off) 8 pixels on the 72 dpi screen at 150% zoom. Offset for the first one will be 0 (origin). The offset for the second one will be 8, but the third one's offset will be 17 (because 8.25 + 8.25 = 16.5 is rounded up to 17)! At offset 16, there is the gap (if a Tab. 3 for your locale system shows no computed font-size rounding at 150%).
It should be possible to create a graphic instrument which would measure the current text-zoom by using some z-indexed-layers: black squares would cover a red background completely, leaving a red indicator (the gap) at 100% zoom. The next layer on z-1 with a slightly different em-width will show a indicator at 120% and so on. That would be a nice demonstration on how errors are somehow useful.
 
 
 
 
Fig. 7
 
[2] Big John at positioniseverything.net did make an interesting test case on this: The 1px Rounding Error Problem. This page helps a lot to get a clue what is going on -- I hadn't the faintest idea -- thank you!
[3] I have just realized that Philippe Wittenbergh at La Chatte Noire did make a test case on this problem (one of his wonderful designed pages): Test For Vertical Spacing Between Block Level Elements in Gecko Browsers.
 

Discussion
Designs become pixel-perfect. A tabbed navigation (Sliding Doors by Douglas Bowman, A List Apart 2003: 160) with text-based markup is accessible because of its text-sizing feature. But with an em-padding added, there are gaps. Or borders are hidden due to overlaps. Return to static pixel lengths? There is no real workaround.
Generally, there are experimental length values: When em/ex-sizing causes a rounding-error in one direction ("height" is to small, -1px gap), there must be a value where the rounding switches to the other direction (+1px overlap) and so on. And some values become a problem first at the x-th iteration, and therefore rounding-errors are not visible at defined zooms. But this is not practicable and not the intention of a accessible technique.
An additional wrapper with the desired background-color or with a positioned background-image will fit the gaps. But overlaps will still occur (fine-tuning the em-padding might shift the rounding to gaps).
I asked Robert O'Callahan if there are workarounds, but the Mozilla "Views"-module owner answered: "Not really". They plan to improve the browser to lay out things in units of 1/60 of a CSS pixel (see mozilla wiki units-page), to cheat with physical and font units to multiples of 1/60 of a CSS pixel, and to implement anti-aliased rendering of elements positioned at fractional offsets. "If we make all those changes then the missing lines problem you see cannot happen. Also, layout will always be consistent (Ncm will always be as high as 10*Nmm, etc etc) at the expense of being slightly inaccurate about physical lengths."
Most of the rounding errors shown on this page (Fig. 1, 3, 4) are fixed since bugzilla Wrong space between block level elements that have no margin was fixed in the nightly build 2005-03-29. And there is some exiting movement (May 05, see bugzilla), they are working on it.
 

Last updated: May 23, 2005
Any ideas, workarounds, comments and corrections are appreciated.