W3C home > Mailing lists > Public > www-style@w3.org > March 2005

Re: Designs that zoom (was : Why reduce font size)

From: Mikko Rantalainen <mikko.rantalainen@peda.net>
Date: Fri, 04 Mar 2005 11:10:05 +0200
Message-ID: <422825ED.8040003@peda.net>
To: www-style@w3.org

Ben Curtis wrote:
>> This truly is a user agent problem and not a CSS problem, and may 
>> disappear as UAs become more precise.
> 
> This is a misunderstanding of the problem. It is not a math error, but 
> rather the accuracy of math that is the problem.

I don't agree. We just have to get comfortable with the idea that 
two elements with "width: 50%" may have a single pixel difference in 
width.

> Say I have 4 floating divs, all width:25%. The viewport is 800px wide, 
> so each is 200px and they fit side by side. I shrink the viewport to 
> 798px, and each div is now:
> 
> 	round(798 * 0.25) = round(199.5) = 200px
> 
> ....totalling 800px, or 2px more than my viewport, causing the last div 
> to drop below the others. I shrink it to 797px, and each div is now:
> 
> 	round(797 * 0.25) = round(199.25) = 199px
> 
> ....totalling 796px, or 1px short of my viewport, even though they total 
> 100% of the width.

This is exactly the error in Gecko engine. See
https://bugzilla.mozilla.org/show_bug.cgi?id=63336#c39 for example.

The thing is, you MUST NOT round the layout coordinates while 
computing "width" or "height". The correct method is to use floating 
point numbers for top,left coordinates and then do

x1=round(left);
x2=round(left+width); // != round(left) + round(width) !!
y1=round(top);
y2=round(top+height); // != round(top) + round(height) !!

(origin at top left corner)

I think CSS DOM (is that the right term to use?) is allowed to 
return floating point numbers for all top,left,....,width,height so 
you're not required to round anywhere else but in the final 
rendering stage.

> No matter how precise the UA is, this will be true. The only solution 
> is the elimination of pixels (either by pixels so fine the human eye 
> cannot discern them or fudging through anti-aliasing vector-based 
> drawing).

Or just render some of the boxes with different width. If you have 
two elements (one blue and one red) with "width: 50%" and three 
pixels to fill you have'll end up with two red pixels and one blue 
pixel OR one red pixel and two blue pixels. In simple case like this 
one could use antialiasing and select average for the middle pixel. 
But antialiasing correctly isn't that easy: to get correct results 
in case like this

<div style="color: red;    width: 20%">
<div style="color: blue;   width: 10%">
<div style="color: green;  width: 30%">
<div style="color: yellow; width: 20%">
<div style="color: black;  width: 20%">

when you have space for one pixel in layout, you would have to 
compute weighted average of 5 elements to get correct pixel color. A 
more complex case would be a table with some elements with colspan 
and rowspan so antialiasing engine would have to compute areas for 
every element. And that table would hit the target pixel only 
partially. Throw in background images and you're in a mess you 
really don't want to be in. An "easy" way would be to supersample 
the canvas 10x and downscale for the resulting image. But you would 
still have to use the correct rounding method (above) to get the 
*correct* supersampled image in the first case. And supersampling 
would hit CPU really hard for nearly vanishing improvement in rendering.

-- 
Mikko
Received on Friday, 4 March 2005 09:10:10 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 27 April 2009 13:54:36 GMT