Opera further messes up the vendor prefix mess
As hard as it is to believe, the mess of vendor prefixes is actually worse than I thought given Opera’s current implementation of -webkit- hijacking.
Right now, opera treats -webkit- as an alias of -o- for certain sets of properties. For the sake of argument let’s use text-shadow as an example.
.myBox {
-webkit-text-shadow: 0, 0, 9px, #000;
-moz-text-shadow: 0, 0, 9px, #000;
-o-text-shadow: 0, 0, 9px, #000;
-ms-text-shadow: 0, 0, 9px, #000;
text-shadow: 0, 0, 9px, #000;
}
This is a fairly typical block of CSS, and it’s authored with the “put the unprefixed version at the end” methodology. The thinking behind this was an echo of what you’d do for supporting RGBA: you specify a property & value pair twice, with the fallback RGB first so that old browsers would apply that colour (the second rule being invalid for them), and new browsers would apply the RGBA (because that’s valid for them, and over-writes the prior declaration), like so:
.myBox {
color: rgb(0,0,0);
color: rgba(0,0,0,0.5)
}
Note however that copying this idea for vendor prefixes was always flawed thinking and should never have had any effect. The reason is two-fold:
- Vendor prefixes are supposed to target a single specific engine.
- W3C consensus is that as soon as an un-prefixed version is rendered by an engine it should no longer render the prefixed version
Here is how the W3C say prefixes ought to be treated when at draft and CR stages. I believe that all vendors were happy with this except Apple, however I can not find an authoritative resource to prove that - if anyone knows of one please let me know
What does that mean? It means that a browser is supposed to discard any prefix that is not specifically targeting it’s own render engine. For the case of Opera that means the ruleset above becomes this:
.myBox {
-o-border-radius: 9px;
border-radius: 9px;
}
Now, given that the W3C tells vendors not to support un-prefixed properties if they are currently supporting a prefixed version, then the last rule should never be applied if the -o- prefix one can be. Similarly, if the non-prefixed rule can be applied then the W3C instruct vendors not to support a pre-fixed version. A prefix and an un-prefixed version of the same property are designed to be mutually exclusive. Most vendors seem pretty good at pulling support for prefixed properties once an un-prefixed version is shipped (notable exception: Apple).
This is all pretty simple. It has the ramification of meaning that there is no cascade for vendor prefixes - source order should never matter, by design.
Where Opera is screwing up
Opera is breaking one of the rules by interpreting -webkit- as being -o-, this is a different argument and more detail is found here. Even this should not complicate matters really: if an author has a -webkit- and a -o- prefixed property, it seems blatantly obvious that the author is explicitly intending opera to get the -o- version. And so if both prefixes are there, Opera should honour the authors obvious intent and render that one, never the aliased -webkit- one.
Alas, no. What Opera actually does is the same as in the color example: it renders whichever is last in the source order. That, to me, is quite obviously broken and means that source order suddenly matters, in cases where previously it didn’t, and by design it shouldn’t. This is my major problem with Opera’s current implementation because it is a practical problem. I accept that Opera isn’t going to stop hijacking -webkit-, but it should be much smarter about when it does and when it does not. The current behaviour can break existing sites because the new Opera behaviour makes source order matter, where before it did not.
But what about when there isn’t an -o- prefix? Well then that’s fine, just interpret the -webkit- one as being -o- and carry on as before.
But yet again Opera screws up. Because if the prefixed version is last in the source order, it will apply that even if Opera’s engine can render a non-prefixed version Update: All other browsers would do this too, but see why it’s less of an issue for them.
What ought to be happening
- If an un-prefixed version is renderable, all prefixed versions should be invalid and un-renderable.
- If a -webkit- prefix is available and Opera is capable of rendering it, render it unless:
- If an un-prefixed version is not available and an -o- prefix is declared in the rule, in which case always render the -o- version
Updated article to clarify browser behaviour for other vendors
Entry Information
- Posted:
- Sat, 12th May 2012 at 15:05 UTC
- Filed under:
- Tags:
Comments
skip to comment form"But yet again Opera screws up"
If Opera screws up, so do the webkit browsers then:
"If an un-prefixed version is renderable, all prefixed versions should be invalid and un-renderable."
Sadly, even though that should be the case, it's not. A simple test in, say, Google Chrome using border-radius followed by -webkit-border-radius shows that the latter applies…i.e. internally Chrome seems to simply have these as equipotent aliases. Opera's behaviour, in this respect, matches Chrome (and Safari, etc).
As mentioned in the article, I was fairly sure Apple were not on board with the W3C proposal for how to handle vendor prefixes, so it's no surprise Webkit is wrong too. And it's not excuse either. Webkit is broken. How does that let Opera off the hook?
If a kid throws rocks at other kids, an excuse of "I'm just doing what the other kid did" doesn't wash.
Ignoring Apple or anyone other vendor: What practical benefit is there to Opera in behaving in this seemingly counter-intuitive way?
Even I'm getting a bit fed up of people pointing the finger solely at Opera on this vendor prefix business, so I can't imagine how the Opera guys must feel.
As Patrick has just pointed out, WebKit browsers (some of them at least) exhibit the same behaviour and yet no-one points any finger of blame at them.
"I was fairly sure Apple was not on board".
Ok, quick test shows me that Firefox behaves exactly the same wrong way as well, and I suspect IE too (but couldn't be arsed to test). See http://people.opera.com/patrickl/proto/unprefixed-vs-prefixed/
I do find it interesting though that, even though you mention that "Apple was not on board", you then go on to single out how "Opera screws up". Those seem to be slightly different statements for exactly the same thing. Say it like you mean it then: "Google Chrome, Safari, Firefox (possibly IE) and Opera screw up!"
Opera is getting ire for vendor prefixes because as of now Opera is the only vendor *actually* messing with the system. This article is about Opera's behaviour, and that's why I say Opera in it. I do agree it's damned annoying that Webkit also misbehave, and I'm saddened to see Mozilla also not following the W3C's take on this.
A year or so ago, Microsoft were in Opera's shoes, over the same issue. They got a lot of shouting, and in the end backed down. People forget this. Opera is not the first to have suggested this, and drawn ire - but Opera's the first that have done it anyway.
Webkit have been largely shown to do their own thing with an attitude of f*** everyone else. Hence the srcset debacle now ( http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-May/035786.html ) - where an Apple representative did their own thing and ignored a years worth of effort by a lot of people, then shoved their own proposal forward. At best it shows a lack of due dilligence in researching the issue before coming up with their own solution, and at worst it show's Apple to be incredibly ignorant of anything outside their own offices.
So, no, this isn't an "everyone pile on opera and ignores others" thing at all. Nor would it matter if it were - if Opera’s reasons are solid reasons that benefit site-authors and website visitors alike, then Opera should be able to clearly defend it’s actions in this matter, and convince everyone else of them too. Resorting to “but other people do this too!” arguments helps no one.
I hope that should Mozilla or Microsoft (once again) join in with Opera's behaviour in regard to prefixes, a similar level of feedback is directed at those companies too.
I should also add that, given the nature of how things work for other vendors (they only interpret their own prefix code) and long promoted and popular coding practice (un-prefixed goes at the end) - no other vendor has a real-world problem in the manner that Opera now does.
That doesn't excuse the fact that other vendors are not obeying the W3C concensus; but it does at least explain why so little has been mentioned about it before - it's not a real world problem.
Opera's behaviour will make it a real world problem in Opera, because it now matters whether an author put -o- before -webkit- or not.
Matt wrote:
"…if Opera’s reasons are solid reasons that benefit site-authors and website visitors alike…"
And right there, you've nailed it. Because of WebKit's dominance on the mobile platform, coupled with an overall lazy attitude and outright scorn by some authors for any browser other than WebKit, sites that should render properly in Opera (Mobile) weren't. End users suffered, but they didn't blame the real culprits (lazy apple fanboi web authors) but instead figured that the browser is broken. Opera's reasons are solid and totally understandable - they are making up for author screw-ups, plain and simple.
As for the current W3C spec… those that know me know I am a long-time supporter of the W3C and of their standards process, but if every browser out there is doing it contrary to what the spec says, it seems that the CSS Working Group need to go back and do some serious re-thinking. The W3C don't *DICTATE* standards, they record them and codify them so that everyone has the same (hopefully neutral) playbook to work from.
More than one blog post I've read suggests that both the conventional authoring order and the lack of cascade seem to be at issue here. Perhaps what really needs to happen is the following:
1) add the non-prefixed property first, then the vendor prefix:
.myBox {
text-shadow: 0, 0, 9px, #000;
-webkit-text-shadow: 0, 0, 9px, #000;
-moz-text-shadow: 0, 0, 9px, #000;
-o-text-shadow: 0, 0, 9px, #000;
-ms-text-shadow: 0, 0, 9px, #000;
}
2) use the same cascade/default rules as font-face selection… work your way down the list until you find something that the browser can do something with.
I don't claim to be a CSS guru (far from it), but it strikes me that this pattern *could* work. More importantly however is that the W3C CSS WG need to recognize that there *is* a problem and "steady as you go" is not the answer. Finally, blaming Opera for standing up and saying that there is a problem, and they are going to fix it in their house regardless of what others say or do, is both smart business, a brave move, and commendable in my books. The last thing anyone should be doing is calling them out as "bad" (reserve that for WebKit - or lazy authors - if you really want to find a villain)
And how is that a problem?
In real life, authors duplicate those declarations and then add the prefix, as far as I know they have no reason to change the property value (with rare exceptions may be).
So unless I'm missing something (which would not be the first time), I don't see how the order matters here…
@John : I understand Opera's reasons for implementing support for -webkit- and while I don't agree with it, I am not arguing that they should stop - that boat has sailed. The point of this post is to show that the method in which Opera is deciding when to use -webkit- over -o- is wrong. Opera should always use an -o- prefix where present and ignore -webkit- if so. Because the site author has specifically gone out of their way to tell Opera something specific - that author can never have thought their source order between -o- and -webkit- would have any effect. Because it never did. So Opera's current "use whichever's last" behaviour can cause Opera to ignore a specific instruction by the author in preference for a specific instruction the author aimed at a different browser. Opera’s current method means that inferred cascade will trump explicitly targeted properties. That makes no sense at all.
Ah, Thierry stole my thunder, that was my follow-up comment.
So, one of the main points of the article, as already discussed "The current behaviour can break existing sites because the new Opera behaviour makes source order matter, where before it did not."
As demonstrated in my comment, this is not true, as the source order clearly matters in WebKit and Firefox (and probably IE). So really what remains is "if both prefixes are there, Opera should honour the authors obvious intent and render that one, never the aliased -webkit- one"
You talk about the real-world problems this will cause, but in the real world what I see most of the time (when authors DID bother to add -o-) is what Thierry said (and what your example code - which uses some exotic text-shadow syntax, btw? - also does): the exact same values, just nicely prefixed plus unprefixed. So, in the manner of "if a tree falls in the woods"…if all the values are actually the same (and keep in mind that Opera is only prefixing a handful of -webkit properties which are fairly stable, so syntax is the same in all browsers), whichever one is the "real" one that the browser picks is an academic question, no? The only situation where the aliasing is an issue is where an author very explicitly said something like "Opera should only get a 2px border radius, whereas WebKit should get 5px" or some such. Is that so common?
@Thierry and Patrick:
Real world problems are documented here, one is Modernizr, which is not a trivial thing:
http://www.sitepoint.com/opera-css3-webkit-prefix/#fbid=0_y3A-CP-f3
@Patrick:
You miss the detail. Source order between -webkit- and -o- matters for Opera users now. It has never mattered before because no browser could render both. That's the specific problem, and it is unique to Opera.
Matt, on skimming that sitepoint article the only two hard problems I can see are:
1) "If your site uses differing -webkit and -o values, it will now be affected by CSS cascade rules" which, as I said, is an edge case most of the time as developers (if they cared about -o- at all) simply copy/pasted the same values for each prefix. The only developers that are adversely affected by this are those that very knowingly and explicitly fed different values for -o-. They'll now have to mind their source order. As they're already a large minority, and are actually aware of -o- in the first place (as they're likely to test), and Opera chose to at least have a consistent (rather than automagic) way of interpreting -webkit- and -o- based purely on source order, I'd posit that they'll manage fine.
2) The Modernizr thing is certainly a problem, but that's purely because Modernizr.prefixed is a helper function (incidentally made exactly because vendor prefixed stuff is obviously burdensome to devs, as it assumes the same values for the properties as well, just explicitly prefixed for the current browser iirc) that didn't take that behaviour into account. Next iteration of Modernizr can fix that. Incidentally, I'm missing why Craig uses the example of "prefixed()" to then talk about "you can’t rely on Modernizr-like detection code"…prefixed isn't about detection, right? And Opera won't alias stuff it doesn't support…so again I'm kind of missing the point of that part of the sitepoint article (then again, I haven't extensively used Modernizr before, maybe I'm missing the obvious).
"You miss the detail. Source order between -webkit- and -o- matters for Opera users now."
No, I'm not missing the detail. I'm asking if this is actually an issue in the real world, where preprocessors or utility functions or simple copy/paste usually end up with a whole block of the same exact values, just neatly prefixed and unprefixed…which I'd posit is where the majority of vendor prefixed things that use both -webkit and -o are…
Regardless of whether a WebKit prefix has the same value as an Opera prefix, Opera should allow the Opera specific one to take precedence.
Same goes for Firefox, Chrome, Safari and IE. If an author has provided a vendor prefixed version, then that should be chosen (unless the non-prefixed one is supported).
Regardless of whether this is an edge case, it is simple to eliminate *all* edge cases by using the behaviour I mention rather than the strange "cascade" behaviour Opera currently does. That's a 100% problem removal - a problem Opera itself has introduced by treating vendor prefixes as it has chosen to, rather than the seemingly obvious and more rational "If i said opera I meant opera" case.
How could modernizr *possibly* have taken Opera's non-conformant and unprecedented behaviour into account? This is not a modernizr bug. The bug is with Opera's chosen implementation for supporting multiple pre-fixes. Modernizr is not at fault that a vendor didn't think through the ramifications of the way Opera deals with the conflict created when Opera chose to support a vendor prefix not its own.
Also, I'd argue that while niche, the problem Opera has now introduced is every bit as big as the problems supposedly being addressed by supporting -webkit- in the Presto engine. Problems I remain unconvinced about. I've yet to see any example other than LinkdIn's log-in form where accessibility is hurt by a website not including an opera prefix in its CSS. Oh I’ve seen problems with UA sniffing, but that is not the same issue. The move Opera have made in supporting some -webkit- CSS properties smells much more like trying to protect market share through feature support than it does a genuine accessibility issue.
The strange cascade behaviour is in line with the strange cascade behaviour that all other browsers also have wrt unprefixed/prefixed.
Did I blame Modernizr for not foreseeing this? No, so don't make it sound like I'm saying it's their *fault*. What I am saying is that this can be fixed at Modernizr's end…it wouldn't be the first time Modernizr has to add code around individual browser behaviours (if you check some of the acrobatics they have to do for certain browsers that lie, pretending to support something when in fact they don't other than simply having added a stub property or function that does nothing).
"I've yet to see any example other than LinkdIn's log-in form" this sounds like the quest for transitional fossils to disprove evolution. "Yeah, this skeleton has traits from these two species…but to *really* prove evolution, where's the in-between stages?" ad infinitum?
To clarify my position: I'm personally in agreement that -o- should take precedence over -webkit-, but what I do contest is the extent by which Opera, in your words, "screws up" - in exactly the same way that all other browsers screw up when it comes to prefixed/unprefixed. As I said on the twitters, I think your article is weakened by its attempt to single out Opera's behaviour that goes oh so much against W3C advice, when all other browsers do the same thing. If your core beef is with -webkit- should only be aliased when there's no -o-, then concentrate on that, as otherwise the discussion can get easily derailed by reality-checking how all other browsers behave as well.
In terms of burden of evidence, let me turn this around for a second: I remain unconvinced that there are many sites out there that *explicitly* want to serve different values for the handful of aliased properties to -webkit- and -o-. I've yet to see any example other than strawman pseudocode
Patrick:
You said "that's purely because Modernizr.prefixed is a helper function ( … ) that didn't take that behaviour into account".
If that isn't a sentence blaming Modernizr for not predicting how Opera's new behaviour would break it, I don't know how else it should be read. Yes, Modernizr can likely fix it - but now the burden of fixing an Opera generated problem is on all site owners to update their website, instead of on Opera to fix its wonky implementation. How is that the right thing?
The strange cascade behaviour Opera uses is indeed in line with all other browsers (depressingly); however it is not an issue in all other browsers, because no other browsers alias pre-fixes, and most authors put the un-prefixed properties last (which ought not matter if the W3C's guides were adhered to, but which does. Regardless, the end result is as expected and in line with what the W3C states should happen. Except for Opera, now).
With regard to Opera choosing to alias at all: if it's such a huge problem for Opera and a genuine problem for users, it shouldn't be difficult to show more than one example that clearly justifies Opera's argument about 'fixing a widespread accessibility problem'. Web developers are skeptical, I'm far from the only one. So, where is this proof? Yes, the burden is on Opera to disclose proof because it's Opera who have performed an action that changes expected behaviour of current style-sheets. If you want developers to believe this is a good choice by Opera you do have to convince them. Otherwise, Opera will continue getting more ire. Justifiably.
The article was written about -o- and -webkit- specifically, but in order to give context for people to understand, I explained the situation Opera has found itself in. I see nothing wrong with that, and I have not argued that Opera should revoke its decision to alias -webkit- for -o- (though I believe it should, that boat has sailed). Once more:
1) The cascade issue is less relevant to other vendors because they are not aliasing prefixes.
2) The behaviour of other browsers is irrelevant to this case. If Opera have a strong argument for using a cascade to determine when to use -webkit- rather than an -o-; state it.
I have stated that when an author has written -o- they are clearly and obviously expecting to target Opera. It's also clear and obvious that no author can have expected their -webkit- prefix to ever address Opera too. So, where is the benefit of treating prefix priority in order of authoring, rather than always treating -o- as primary in Opera?
With regard to the burden of evidence sentence:
Site's using modernizr feature detection. Of which there are a lot. How many are breaking? I don't know, but this is what is usually referred to as "low hanging fruit" - it's trivial for Opera to ensure that *no* sites break in this way by refactoring the behaviour of the aliasing to that described above. Which is fairly common sense. In doing that all sites using modernizr would operate as before the aliasing was introduced. I.e., correctly and as expected.
But then, the burden of evidence isn't on me as a developer. It's on Opera as a vendor, assuming they don't want to further alienate/annoy the community. Why? Because Opera are changing the status-quo, and it is down to Opera to prove why it is beneficial to do that - especially when that changed behaviour has a negative impact on other areas or existing code.