W3C home > Mailing lists > Public > www-style@w3.org > January 2015

Re: [cssom] Serializing non-opaque colors, background-position keywords

From: Simon Pieters <simonp@opera.com>
Date: Thu, 29 Jan 2015 12:43:22 +0100
To: www-style@w3.org, "Boris Zbarsky" <bzbarsky@mit.edu>
Cc: "Tab Atkins Jr." <jackalmage@gmail.com>
Message-ID: <op.xs72uk0lidj3kv@simons-mbp>
On Wed, 28 Jan 2015 18:54:44 +0100, Boris Zbarsky <bzbarsky@mit.edu> wrote:

> On 1/28/15 5:10 AM, Simon Pieters wrote:
>> How should color: rgba(5, 7, 10, 0.9) be serialized? Gecko round-trips
>> alpha as 0.9 but Blink makes it 0.901961. I think Gecko faithfully
>> round-trips two decimals for colors.
>
> Yes.
>
> Specifically, Gecko's internal storage for the case above is a 32-bit  
> integer, 8 bits each for RGBA.  Which means the 0.9 gets coverted to an  
> integer in the range [0,255], by multiplying it by 255 and then  
> rounding.  This produces 230 in this case.  I assume Blink does the  
> same, since 230 / 255 == 0.901960784314...

Yeah.

> In any case, when converting the integer back to a float, Gecko does the  
> following (code at  
> <http://hg.mozilla.org/mozilla-central/file/9b6b80222e66/layout/style/nsStyleUtil.cpp#l567>  
> but reproduced below as pseudo-code with more extensive comments):
>
>    // Produce a float with at most two digits after the decimal point,
>    // modulo representability issues.
>    rounded = round(alpha * 100.0 / 255.0) / 100.0;
>    if (round(rounded * 255) == alpha) {
>      // We have a float which would give us the observed alpha value;
>      // use it.
>      return rounded;
>    }
>    // Produce a float with at most three digits after the decimal
>    // point.  More precision that that is pointless, because there are
>    // only 256 possible values of "alpha" anyway, so the 1000 values we
>    // can produce here cover all of them.
>    return round(alpha * 1000.0 / 255.0) / 1000.0;
>
> This faithfully round-trips two decimals, preserves about 1/4 of  
> three-decimal values, and rounds off all values with more precision to  
> three decimal places (and in fact only to the subset of  
> three-decimal-place values that are multiples of 1/255).

Thanks!

>> Should we specify Gecko's behavior
>> of rounding to a "nicer" number?
>
> We feel pretty strongly that this behavior is much better for authors in  
> typical situations.  The spec obviously doesn't require browsers to  
> store alpha as an 8-bit integer, but it could require that if they do so  
> they must use an algorithm like the above when serializing the  
> (already-rounded, just in different units) value.

Yes. I agree it seems better for authors.

>> Similarly for 'opacity' (although that is represented with higher
>> precision I think).
>
> I'd think opacity is typically represented as an actual float... though  
> of course technically CSS requires representation as an  
> infinite-precision decimal or something.

In Blink opacity:0.4 doesn't round-trip as 0.4 with getComputedStyle:

http://software.hixie.ch/utilities/js/live-dom-viewer/saved/3388

but it does round-trip for element.style:

http://software.hixie.ch/utilities/js/live-dom-viewer/saved/3389

The getComputedStyle case gets a double -> float -> double roundtrip. For  
the .style case it doesn't go through float.

Filed https://code.google.com/p/chromium/issues/detail?id=453288

As for Gecko, rune helped me find this:

http://lxr.mozilla.org/mozilla-central/source/xpcom/string/nsTSubstring.cpp#949

Output up to 6 decimals, but remove trailing 0s. Handling of scientific  
notation is also interesting. There the conversion from float to double is  
still visible with e.g.  
http://software.hixie.ch/utilities/js/live-dom-viewer/saved/3390

IE11 has the same behavior as Gecko for the cases I've tried (including  
sci-not).


>> How should background-position: 0% top be serialized? For element.style,
>> Gecko round-trips keywords, Blink converts to percentages.
>
> Interstingly, the devtools in Blink show "0% top" in this case, so  
> either they're not using the actual parsed CSS data structures or the  
> latter are in fact storing the keyword and just converting to 0% at  
> serialization time...

OK. Devtools might be using getMatchedCSSRules() which maybe more  
faithfully preserves the input.

IE11 roundtrips percentages and keywords for .style but converts to  
percentages for .getComputedStyle.

http://software.hixie.ch/utilities/js/live-dom-viewer/saved/3392


On Wed, 28 Jan 2015 19:52:56 +0100, Tab Atkins Jr. <jackalmage@gmail.com>  
wrote:

>> == Non-opaque colors ==
>
> We store alpha with the same resolution as the other channels, as a  
> single byte.
>
> We could maybe round to the nearest .01 for serialization (which will
> always round-trip values of that precision), but I doubt we'd want to
> expand our precision, as it currently allows us to store a complete
> color in an int32.
>
> (Or we could do what Boris suggests, and return two or three digits,  
> depending.)

Two digits can't represent all possible values of a byte. e.g. we need  
0.004 to represent 1. So we should probably do what Gecko does.

Interestingly, IE11 seems to do something different entirely.

http://software.hixie.ch/utilities/js/live-dom-viewer/saved/3394

Alpha of 0.1234567890123456789 gets serialized as 0.123456.

>> Similarly for 'opacity' (although that is represented with higher  
>> precision
>> I think).
>
> I would be totally fine with specifying that opacity must be
> serialized with 2 or 3 digits.

OK. Presto serializes at most 2 digits. Are people OK with that? Or is the  
Gecko/IE approach better?

>> == background-position keywords ==
>>
>> How should background-position: 0% top be serialized? For element.style,
>> Gecko round-trips keywords, Blink converts to percentages. For
>> getComputedStyle, both convert to percentages. I think the spec for
>> background-position says keywords compute to percentages.
>
> I'm fine with either percentages or keywords, as long as we don't have
> to remember which was specified and return it.  In other words, I'm
> okay if "top" always becomes 0%, or 0% always becomes "top" (or
> "left", whatever), but I'm not okay with 0% becoming 0% and "top"
> becoming "top".

OK. Why?

Are Gecko/IE OK with not differentiating keywords and percentages in  
element.style?

> I lean slightly towards percentages, though, as that means the
> serialization doesn't suddenly change at a few magic values.

-- 
Simon Pieters
Opera Software
Received on Thursday, 29 January 2015 11:43:55 UTC

This archive was generated by hypermail 2.4.0 : Friday, 25 March 2022 10:08:50 UTC