Re: Dropping Prefixes Early on Transforms/Transitions/Animations

On Fri, Feb 17, 2012 at 2:08 PM, Sylvain Galineau
<sylvaing@microsoft.com> wrote:
> I think it can help somewhat, actually. If you need to work around one
> browser's bug or rendering issue by tweaking the value and the new value
> is still valid for the other UAs, you either end up falling back to what
> the buggy UA accepts across the board, or you'll do what prefixes do - browser
> sniffing - in much uglier ways.

To the contrary -- browser-sniffing based on the UA string is much
less ugly.  Browser-sniffing using prefixes means you have to use the
prefixes even when you don't want to UA-sniff.  This means that 1)
your code is much more verbose even in the common case where you want
a simple effect that's more or less interoperable, and 2) in the rare
case where you do want to give different markup to different browsers,
nobody will notice because they're not going to spot the difference in
the long otherwise-identical lines.  It also means that you're doing
engine detection instead of feature detection, which is bad.

If the point of prefixes is only to allow UA-sniffing to get around
bugs after the syntax is solidified, then browsers should all just
implement both prefixed and unprefixed versions.  That way you can use
the unprefixed version in most cases, and if one browser has a bug you
want to work around, you can use the prefixed version to override its
behavior.  This argument doesn't justify browsers not supporting the
unprefixed version.

Also, allowing authors to browser-sniff using prefixes is too crude to
be a replacement for real browser sniffing.  It doesn't let you
distinguish browser versions.  Alan gives a good example below where
Safari and Chrome differ, because their 3D transforms implementations
are different.  Chrome will also fall back to an incompatible
implementation if there's no usable 3D acceleration.  And of course,
new versions of browsers fix bugs and introduce them.  None of these
use-cases are served by prefixes -- you have to use JS-based
browser-sniffing anyway.

On Sat, Feb 18, 2012 at 7:04 AM, Alan Gresley <alan@css-class.com> wrote:
> For all your information. Safari 5.1.1 seems to show some 3D virtual space
> constructs correctly while Chrome 17.0.963.56 fails them. They are in a bug
> with intersecting planes [1] and in another similar bug where certain
> backgrounds go missing when pivoting when they are positioned from these
> intersecting planes [2]. Here is a test case of the later bug [3].

Yes, there are still bugs in browsers' transform implementations.  I
don't think anyone gets intersections right except Safari, and maybe
only on Mac.  However, lots of features are buggy in some browsers,
and that's not helped by prefixing.  In fact, you make my point
beautifully: Chrome and Safari behave differently, but have the same
-webkit- prefix!  So the prefix doesn't help anything.  You have to
use regular old browser sniffing.

> Aryeh, does a mozilla-central build handle these test correctly?

Definitely not all of them.  See
<https://bugzilla.mozilla.org/show_bug.cgi?id=689498>.  But the
question isn't just "Do browsers behave differently?"  It's "Do
prefixes help authors work around this browser difference?"  In this
case (intersections in 3D), I believe the answer is no.  There's no
way that I can think of to work around the bug at all except breaking
up the elements into different elements yourself, and that will work
fine in Safari too.  There's no need to serve anything different to
different browsers at all.  And if there were, prefixes wouldn't help,
because you need to distinguish Chrome from Safari.

I've spent a whole lot of time looking at browser behavior for
transforms lately, and everything I can think of is best worked around
by serving the same CSS markup to browsers.  Prefixes don't make any
of the bugs I can think of easier to work around.  Just for
concreteness, here's a review of all the transform bugs I've fixed in
Gecko, and what the best way is to work around them prior to my fix:

--------

1) https://bugzilla.mozilla.org/show_bug.cgi?id=719054 "matrix() and
matrix3d() with length units should be parse errors".  Best
workaround: do not specify length units in matrix() and matrix3d().
Then the markup will work the same in all browsers.  You have to do
this to accommodate non-Firefox browsers, so there's no way to do it
with less work.

2) https://bugzilla.mozilla.org/show_bug.cgi?id=724750 "3D transform
backface-visibility has no effect when applied to an element with
display:table".  Best workaround: add an extra wrapper that
backface-visibility will apply to instead.  Alternatively, specify
::-moz-table-outer { -moz-backface-visibility: inherit } (not sure if
that would work).  Then the markup will work the same in all browsers.
 You have to do one of these things to accommodate unfixed Firefox, so
there's way I can think of to do it with less work.

(The -moz-table-outer fix involves a prefixed selector, but it's
totally made up by Mozilla, not standardized, and its behavior only
makes sense in the context of Gecko's table implementation, so
unprefixing it is not an option.  That fix would still work if
backface-visibility were unprefixed, since other browsers would ignore
the rule because they don't recognize the selector.  So it doesn't
rely on TTA being prefixed.)

3) https://bugzilla.mozilla.org/show_bug.cgi?id=722463 "Transforms
should not work on non-replaced inline elements".  Best workaround: do
not specify transforms on non-replaced inline elements -- move the
transforms elsewhere depending on your needs.  Then the markup will
work the same in all browsers.  Such transforms won't work in WebKit,
and will behave inconsistently across other browsers, so you can't
usefully specify them cross-browser either before or after this bug
fix.

4) https://bugzilla.mozilla.org/show_bug.cgi?id=721136 "transform
property serialization doesn't normalize case".  Best workaround: call
toLowerCase() before you try to parse serialized transform lists.
Then the script will work the same in all browsers.  You could try to
parse it differently if you're reading from MozTransform vs. other
transform properties, but that's more complicated and less reliable
and doesn't gain you anything, so there's no reason to try.

5) https://bugzilla.mozilla.org/show_bug.cgi?id=722777 "Tables with
'transform' property set don't act as abs-pos/fixed-pos containers".
Best workaround: add a wrapper and transform that.  Then the markup
will work the same in all browsers.  You have to do this anyway to get
it to work in unfixed Firefox, so there's no way to avoid the work.

6) https://bugzilla.mozilla.org/show_bug.cgi?id=719446
"getComputedStyle().MozTransform shouldn't have "px" in it".  Best
workaround: call .replace(/px/g, "") before you try to parse
getComputedStyle().  Then the script will work the same in all
browsers.  You could try to parse it differently if you're reading
from MozTransform vs. other transform properties, but that's more
complicated and less reliable and doesn't gain you anything, so
there's no reason to try.

7) https://bugzilla.mozilla.org/show_bug.cgi?id=725426 "Incorrect
getBoundingClientRect() for transform-style: flat".  Best workaround:
there is no workaround that I can think of.  If you can't find a
workaround specific to your use-case, you should report a failure
based on feature-detecting the bug.  Failing based on the prefix is a
bad idea because it means you'll fail in Firefox 13 too, even though
it doesn't have the bug.

8) https://bugzilla.mozilla.org/show_bug.cgi?id=725036 "'perspective'
property doesn't reject negative numbers".  Best workaround: do not
specify negative numbers for 'perspective'.  They'll be rejected by
all non-Firefox browsers anyway, and in unfixed Firefox they'll do
nothing useful.  Then the markup will work the same in all browsers.

9) https://bugzilla.mozilla.org/show_bug.cgi?id=715946
"getComputedStyle().MozTransformOrigin and MozPerspectiveOrigin
sometime return percentages".  Best workaround: parse out percentages
and replace them by suitable pixel values, multiplying by the
height/width of the border box as reported by
getBoundingClientRect().height/.width or such.  Then the script will
work the same in all browsers.  You could make this processing
conditional on reading from .MozTransform vs. other transform
properties, but there's no point -- other browsers won't give you
percentages to start with, and Gecko doesn't always give percentages,
so running the other browsers through the Gecko codepath too is
harmless and involves one less conditional.

--------

So that's nine real-world Gecko bugs in transforms that authors might
have to work around.  I picked them without bias, just whatever bugs I
happen to have fixed.  I omitted only bugs that weren't
transform-specific, and one bug that was QoI rather than a spec bug
(https://bugzilla.mozilla.org/show_bug.cgi?id=724614 if you're
interested).  In every single case, the prefixing is of no help to
authors in working around the bugs.

I conclude that barring data to the contrary, we should assume that
prefixing does not help authors work around bugs in most cases.  Even
if it does help in some cases -- does anyone have examples? -- those
cases are not common enough to justify the pain of specifying
everything many times.  We should not make the common case more
painful for the benefit of the rare case.

Moreover, bugs should be worked around by feature-detection where
possible, not based on engine, so prefixes actively encourage authors
to use undesirable workaround techniques.  Even if they were being
widely and effectively used to work around browser bugs, we should try
to prevent authors from doing so, not condone it.

Moreover, even if prefixes were commonly useful for working around
bugs and we wanted to condone that kind of workaround as good practice
(neither of which seems to be the case), that would only argue for
browsers supporting a prefixed syntax *in addition* to the unprefixed
syntax, not *instead of* it.  Then authors could use the unprefixed
syntax in most cases, and use the prefixed syntax for workarounds.


At this point, with all due respect, I do not see any plausible reason
presented by anyone for maintaining prefixes on features whose design
is largely finished but where browsers are still buggy -- even
egregiously so.  Would anyone like to enlighten me?  Features that are
still really in flux and might see significant syntactic changes might
still warrant prefixes, but that's not the case for TTA.

Received on Monday, 20 February 2012 18:45:10 UTC