Opera Mobile Emulator build with experimental WebKit prefix support
CSS vendor prefixes were introduced in CSS 2.1 for vendor-specific extensions with the warning that authors should avoid vendor-specific extensions. CSS Snapshot 2010 extended the definition: "Prior to a specification reaching the Candidate Recommendation stage in the W3C process, all implementations of a CSS feature are considered experimental. The CSS Working Group recommends that implementations use a vendor-prefixed syntax for such features, including those in W3C Working Drafts."
Opera, along with Mozilla, announced at a CSS Working Group meeting (minutes) that we would support some -webkit- prefixes. This is because through our site compatibility work, we have experienced that many authors of (especially mobile) sites only use -webkit- prefixed CSS, thereby ignoring other vendor prefixes and not even including an unprefixed equivalent. This leads to a reduced user experience on Opera and Firefox, which don't receive the same shiny effects such as transitions, gradients and the like, even if the browser supported those effects.
The vendor prefix system is hard to use. It's easy to miss out a vendor prefix when copying and pasting multiple lines, or because a vendor doesn't support a certain feature while you're developing. Some specifications seem to take forever to get to the Candidate Recommendation stage at the W3C, after which vendors are supposed to unprefix their implementations. Some developers erroneously assume that mobile development equals iOS devices, so only use -webkit- prefixes because they don't know or don't care about other browsers. There are many reasons for missing out some prefixes - but the user is always the loser.
Automatic error recovery (#)
One of the HTML5 design principles is "Error handling should be defined so that interoperable implementations can be achieved. Prefer graceful error recovery to hard failure, so that users are not exposed to authoring errors."
CSS is not HTML, of course. But the same principle holds. Using single-vendor code on the World Wide Web that results in non-interoperability is an authoring error. In the same way that the HTML5 parsing algorithm "re-writes" HTML to make tags close correctly in the DOM in order to ensure interoperability, this Labs release tests reacting to certain -webkit- prefixed CSS properties as though they were -o- prefixes in order that users are not exposed to authoring errors.
Builds (#)
In order to test this out, we have prepared Opera Mobile Emulator Labs builds with support for selected -webkit- prefixes.
- Opera Mobile Emulator Labs build for Mac
- Opera Mobile Emulator Labs build for Windows
- Opera Mobile Emulator Labs build for Linux
Which prefixes are affected? (#)
Two different types of prefixes are supported:
-webkit-linear-gradient
-webkit-linear-gradient
and -o-linear-gradient
will behave identically and the following rules will be obeyed when evaluating styles.
- Duplicate properties will not be preserved when both
-webkit-linear-gradient
and-o-linear-gradient
are found. Whichever comes last will override the other. - Which name is in use will be tracked, so if the value is retreived from JavaScript, the prefix is remembered.
Properties
-webkit-
prefixed properties are supported through a CSS property aliasing mechanism, and also will obey the following rules.
- As above, when a
-webkit-
prefixed property and an-o-
prefixed property are encountered, they are treated as instances of the same property, so the latest one (according to usual cascade rules) wins. - When accessing or setting the value of a property through JavaScript, all the aliased names of a property are visible as members of the
CSSStyleDeclaration
object, and they map to the same value.- However, the CSSStyleDeclaration .item(*) function will return the canonical name of the alias, not the name actually used. This point may be changed in the future if it is found to cause problems.
removeProperty
,setProperty
,getPropertyValue
, andgetPropertyPriority
all will work with aliases as described above.webkitTransitionEnd
is aliased tooTransitionEnd
enabling the use ofaddEventListener("webkitTransitionEnd"...)
- If both
addEventListener("webkitTransitionEnd"...)
andaddEventListener("oTransitionEnd"...)
have been used to register a listener, only theoTransitionEvent
will be fired.
- If both
- If the property name is used as the value of another property (as is the case with
transition-property
), the name that was used is preserved.
The properties that have been aliased in this way are:
-o- |
-webkit- |
---|---|
box-shadow | -webkit-box-shadow |
-o-transform | -webkit-transform |
-o-transform-origin | -webkit-transform-origin |
border-radius | -webkit-border-radius |
border-top-left-radius | -webkit-border-top-left-radius |
border-top-right-radius | -webkit-border-top-right-radius |
border-bottom-left-radius | -webkit-border-bottom-left-radius |
border-bottom-right-radius | -webkit-border-bottom-right-radius |
-o-transition | -webkit-transition |
-o-transition-delay | -webkit-transition-delay |
-o-transition-duration | -webkit-transition-duration |
-o-transition-property | -webkit-transition-property |
-o-transition-timing-function | -webkit-transition-timing-function |
How did you choose these? (#)
We decided to alias properties and values for which are frequently used in the wild with a -webkit- prefix and without fallback, but which we already support either under an -o- prefix or unprefixed. To determine which property was frequent, and how often it had fallbacks, we analyzed the style sheets of a large number of popular websites (Alexa top 10,000). Based on that information, we made a subjective judgment.
Just mobile, or desktop too? (#)
Both. Our Desktop and Mobile browsers share the same core. Testing in multiple browsers is hard enough without having to worry about subtle differences between various ports of the same browsers.
What will happen to my site? (#)
One of the following:
If you were just ignoring Opera, and only used -webkit- prefixes, we've just made your site more compatible to Opera users.
In this example, the words "Vital information" were previously invisible to Opera, but visible in WebKit browsers. Now, they are visible in Opera too.
<!DOCTYPE html> <meta charset=utf-8> <style> div {color:white; height:100px; background: -webkit-linear-gradient(top, rgba(30,87,153,1) 0%,rgba(125,185,232,0) 100%); } </style> <div>Vital information</div>
- If you weren't using -webkit- prefixes (you were using the unprefixed variant, for instance), nothing changes and you don't have to care.
- If you've been using both -webkit- and -o- (or unprefixed) and supplying the same value to both, it will keep working just fine and you don't need to care.
If you were using both -webkit- and -o- (or unprefixed), and supplied different values to each, you need to check the order in which they put things in the style sheet. Because these -o- and -webkit- prefixes are regarded as being variants of the same name, the later version will be the one that is applied, whether it is prefixed -webkit- or -o-.
Consider a page that for some reason sends a red gradient to Opera and a blue gradient to WebKit. If the -o- rule comes before the -webkit- rule, Opera and webkit will receive a blue gradient, because the -webkit- rule over-rides the -o- rule:
<!DOCTYPE html> <meta charset=utf-8> <style> div {color:white; height:100px; background: -o-linear-gradient(top, rgba(255,0,0,1) 0%, rgba(125,185,232,0) 100%); background: -webkit-linear-gradient(top, rgba(30,87,153,1) 0%,rgba(125,185,232,0) 100%); } </style> <div>Vital information</div>
Try example 2. Note that current versions of Opera will show a red gradient, this Labs build shows a blue background.
In order to send a rule with different values to Opera, it must be after the -webkit- rule in the cascade (example 3):
<!DOCTYPE html> <meta charset=utf-8> <style> div {color:white; height:100px; background: -webkit-linear-gradient(top, rgba(30,87,153,1) 0%,rgba(125,185,232,0) 100%); background: -o-linear-gradient(top, rgba(255,0,0,1) 0%, rgba(125,185,232,0) 100%); } </style> <div>Vital information</div>
We discussed having the -o- prefixed version always trump a -webkit- version, but that breaks the cascade mechanism of CSS, which make it much harder for authors to debug sites and could have many unforeseen consequences. Therefore, we ask you to make a once-only check.
What about differences in behaviors between WebKit and Opera? (#)
As far as we can tell, the behavior the properties that we have aliased is identical in WebKit and Opera, or at least close enough that the differences will not matter in practice. If it turns out that there are differences big enough to cause breakage, we will consider our options, one of which is to align the behavior of our -webkit- prefixed variant to what WebKit actually does.
Isn't this going to ruin everything and make my life as a developer way more complicated? (#)
No. If you're using vendor prefixes correctly, nothing will change. If you were only using -webkit- prefixes, you get backwards compatibility for some of those in Opera, without harming your iPhone joy.
Why is Opera breaking the Web and interoperability? (#)
We're not. We make a web browser, that allows people to access content on the web. When people block access by certain browsers, whether by omitting CSS rules or actively blocking, we have a duty to our users to access that content.
We're promoting interoperability by silently correcting errors in an entirely predictable way, to benefit users.
Has similar stuff been done before? (#)
All browsers include mechanisms to deal with broken or unintended content. For example, IE6 invented DOCTYPE switching that assumed, from the lack of DOCTYPE that the developer wanted the erroneous IE5 box model. Opera and Firefox had to include bug compatibility with IE6, which is only being removed now.
More recently, Opera Mobile and Safari/iOS supported semicolons as delimiters between values for the viewport meta tag. The spec specifies commas, but authors were using semicolons.
When encountering broken XML (served as application/xhtml+xml), Opera decided to silently reparse the broken document as HTML, rendering the content to the end user, instead of showing an incomprehensible Parsing Failed error.
And, of course, the HTML5 parsing algorithm "rewrites" broken or mis-nested HTML to ensure interoperable DOMs between browsers.
Why are you levelling blame at the feet of us developers? (#)
We're not. Others share the blame too:
- The CSS WG (that includes us) for failing to sufficiently prioritize specs that are seeing wide adoption
- WebKit vendors for not putting much effort in standardizing their proposals, for advertising -webkit- without fallbacks, and for not dropping prefixes at all
- The CSS WG for designing the prefix system, with all its downsides
- Authors and clients who believed it to be legitimate to exclude people because of their browsers
The point of this isn't to blame anyone. It's to get the content to the user.
So I only need to use -webkit- prefixes now? w00t! (#)
Absolutely not. We're doing this now to ensure that there is compatibility with the 13 features we're aliasing. We hope we never need add any more and that we can drop support for these. It remains vitally important to make sure that you code for all browsers, even if they don't have support for a certain feature while you're coding. We suggest this as a pattern that will ensure the cascade functions and any Opera-specific values are rendered:
blah {
-webkit-foo : bar;
-moz-foo : bar;
-ms-foo : bar;
-o-foo : bar;
foo : bar;
}
Added 8 May 2012:
We want to ensure that the vendor prefix system never gets us into this situation again. So, in parallel with this experimental build of Opera Mobile Emulator, Opera's representative on the CSS Working Group, Florian Rivoal, has a proposal to fix the vendor prefixing system:
When a browser vendor implements a new css feature, it should support it, from day 1, both prefixed and unprefixed, the two being aliased. If a style sheet contains both prefixed and unprefixed, the last one wins, according to the cascade.
Authors should write their style sheets using the unprefixed property, and only add a prefixed version of the property (below the unprefixed one) if they discover a bug or inconsistency that they need to work around in a particular browser.
If a large amount of content accumulates using the a particular vendor prefix to work around an issue with the early implementation in that browser, the vendor could decide to freeze the behavior of the prefixed property while continuing to improve the unprefixed one.
(Read the full explanation). This is currently being debated in the Working Group.
This article is licensed under a Creative Commons Attribution 3.0 Unported license.
Comments
Thiemo
Friday, April 27, 2012
Thanks a lot for explaining your decision in such detail. You are right, what matters in the end is the user. However, many people are using Opera as a development tool, especially all the people reading this article. This change will make our live harder because we can't see if we missed a non-webkit property. As a matter of fact you will see a lot more sites relying on the -webkit- prefix only. I totally understand your problem and why you need to solve it but this attempt will make it worse in the long run. Isn't there an other solution like using your browser.js to patch broken sites?
Thiemo
Friday, April 27, 2012
John A. Bilicki III
Friday, April 27, 2012
Do NOT retard Opera because people are incompetent at doing the jobs they're being paid to do.
Show your support for end users by having companies whip lazy and inept web designers or have them fired so competent web designers can take their place. Nature works best!
Thiemo
Saturday, April 28, 2012
Ian Lunn
Saturday, April 28, 2012
http://www.ianlunn.co.uk/blog/articles/concerns-about-opera-rendering-webkit-properties/
Charlie Clark
Saturday, April 28, 2012
Although Eric Meyer has staunchly and lucidly defended (http://www.alistapart.com/articles/the-vendor-prefix-predicament-alas-eric-meyer-interviews-tantek-celik/) the prefix system, Bruce hints that, he at least, considers it to have problems. To recap: prefixes prevent the catch 22 of HTML & CSS development - you can only implement a completed specification but you real world specification must be tested in the real world before completion - by allowing developers not only to suggest features but also to provide working implementations of them. Gradients are a good example how this worked to clarify the semantics of the feature. It is ironic to see them part of this issue. If the issue was only with regard to eye-candy it could probably be ignored but it has also allowed Opera to submit and demonstrate the fantastic page-media extensions.
With hindsight, I can think of several flaws in the prefix approach: firstly, it is cumbersome; secondly, it supposes a level of knowledge of the specifications and their implementations that most developers are not aware of: thirdly, it is not easy to test for, not in the sense of modernizr in checking for support of a feature, but in the behaviour; fourthly, and perhaps most importantly, by including support for experimental features in main releases vendors have inadvertently blessed them. To blame web site makers for using such features to differentiate or enhance their site even though they might only work with their preferred browser is not only naive but fundamentally wrong: making the user experience better is their job. I think it would have been better to limit implementations to lab builds only or provide user control to enable or disable experimental features. Properly handled that could even speed up to adoption or rejection of proposed features. The problem is: would all vendors go along with that? I remember very clearly when Apple launched a Flash-free presentation of one its product that was used browser-sniffing to lock out all but Safari browsers from some CSS 3 transitions.
Thiemo
Monday, April 30, 2012
I created an example page: Why Opera is breaking the web.
Thiemo
Monday, April 30, 2012
Here is an example on what will happen: Let's assume a web developer creates a site in Firefox. The site is finished and he does some checks in a few other webbrowsers. He starts with Opera (for whatever reason, probably because he likes it more than Chrome). He applies some fixes or not, but in the end, the site looks fine. Then he switches to Chrome and there are a few problems. He has to add a few -webkit- properties to work around this. He will never notice these WebKit-specific fixes broke the site in Opera till the client sues him. He has to add Opera-specific -o- prefixed workarounds (or change the order very carefully) to fix problems caused by WebKit-specific -webkit- prefixed workarounds. I'm very sorry but I think this is sick.
Thiemo
Monday, April 30, 2012
Thiemo
Monday, April 30, 2012
Adrian Roselli
Monday, April 30, 2012
Thiemo
Wednesday, May 2, 2012
YongShun
Thursday, May 3, 2012
Frans
Monday, May 7, 2012
The very same thing would happen in e.g. IE8. Good practice is something like
background:solidcolor;
background:hsla(x,x,x,.5) or background:gradient or whatever
It's only slightly more complicated than including both a background-color and a background-image (also something many don't seem to do). Or to put it another way: I've been running into this very same problem for over 10 years whenever I disabled images.
Patrick H. Lauke
Thursday, June 14, 2012
JanGen
Thursday, June 21, 2012
1. -webkit- is for webkit
2. -o- is for opera.
Developers targeting only browsers with large marketshare is a problem, but not a new one. I can remember the times major sites in Holland blocked Opera. Some did it by mistake, some by ignorance, some by purpose
All bad reasons, and IMHO they should be blamed for it. But we live in a free world.
Now Opera is acting irrational and adding confusion, normally I add prefixes in an alphabetical order, but now you suggest -webkit- first and -o- last? That will break everything I did before
And about the new Florian suggestion, I like, but unprefixed first and prefixed last is the opposite we've done before. So there is no clear workflow for developers yet.
IMHO just start implementing the unprefixed property sooner, that will solve most cases.
`We hope we never need add any more and that we can drop support for these. `
If it's just a temporary problem, don't deal with it, it's just about eye-candy. nothing is broken when graceful degradation & progressive enhancement protecting is done properly: (test a website without images).
I hope Opera will not implement this, better fight for their right: -o-
Alternatives
1 UserJS
2 (default) Extension
3 At least is should be configurable, like experimental webkit prefix support:
1,2 with code like:
opera.addEventListener('BeforeCSS', function(userJSEvent){
userJSEvent.cssText = userJSEvent.cssText
.replace(/-(webkit|o)-(border)/g,'$2')
.replace(/-(webkit)-(gradient|transform|transition)/g,'-o-$2');
}, false);
or 2 with http://leaverou.github.com/prefixfree/
Better just support the unprefixed version faster.
Thiemo
Friday, July 6, 2012