Opera Mobile Emulator build with experimental WebKit prefix support

By Bruce Lawson

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.

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, and getPropertyPriority all will work with aliases as described above.
  • webkitTransitionEnd is aliased to oTransitionEnd enabling the use of addEventListener("webkitTransitionEnd"...)
    • If both addEventListener("webkitTransitionEnd"...) and addEventListener("oTransitionEnd"...) have been used to register a listener, only the oTransitionEvent will be fired.
  • 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>
    
    

    Test example 1.

  • 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

  • photo

    Thiemo

    Friday, April 27, 2012

    (This comment was posted first but moved down when I inserted a link.)

    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?
  • photo

    Thiemo

    Friday, April 27, 2012

    I think you missed my point. I was talking about missing non-webkit properties. Since -webkit- will work "everywhere" it does not matter any more if we web developers care about the -o- or unprefixed properties. Many developers are using Firefox or Safari and just do a quick check in Opera. They don't see a difference any more even if they missed a vital CSS property. And about your browser.js, you only need to fix a few sites where something is invisible or otherwise broken like in your example. On most sites it does not matter at all if a corner is angular or a transition is done without an animation. Most people won't even notice. The properties we are talking about are mostly bling-bling and not breaking user experiences except for a few cases. Did your research include a number of sites where a feature is actually broken because of a missing property?
  • photo

    John A. Bilicki III

    Friday, April 27, 2012

    KILL IT WITH FIRE!

    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!
  • photo

    Thiemo

    Saturday, April 28, 2012

    @John: I love Opera (both the webbrowser and the company) very much but this change makes our life as a developers more complicated and, whats more important, it makes the problem (like incompetent people using "-webkit-box-shadow" only) worse. This will make more incompetent people using only the -webkit- properties and ignoring the spec. I wish they would address this in this document.
  • photo

    Ian Lunn

    Saturday, April 28, 2012

    I've written my concerns about what I've seen so far in the experimental Opera Mobile Emulator and provided some code examples that could cause issues with existing applications here:

    http://www.ianlunn.co.uk/blog/articles/concerns-about-opera-rendering-webkit-properties/
  • photo

    Charlie Clark

    Saturday, April 28, 2012

    Regarding who is being punished and who is being rewarded. This is a red herring. Unfortunately, because developers are punishing users by failing to use the prefix system correctly, there is little to be gained by pointing the finger. You could raise alerts in the browser saying that the site is poorly coded but that is only likely to annoy a user even more. That's what error logs are for if anyone is interested.

    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.
  • photo

    Thiemo

    Monday, April 30, 2012

    About "not breaking the specs", this does break the specs. I almost forgot but this Twitter user nails it down: "A page isn’t 'poorly authored' when the author decides only WebKit supports a new feature well enough to use it." In other words, a property prefixed with -webkit- is supposed to work only in webbrowsers based on the WebKit engine. I have to ask this question again: How many sites are actually broken because of a -webkit- property? How do you know which site in your research is actually erroneous and which site uses a -webkit- property on purpose?

    I created an example page: Why Opera is breaking the web.
  • photo

    Thiemo

    Monday, April 30, 2012

    No, it's not "predictable and consistent" since it changes the behavior of the Opera webbrowser. Opera not only starts reading properties it was never supposed to read, it starts ignoring unprefixed properties (see my example). This will break existing websites. And this is not just a theory, this is how CSS is written in reality: Unprefixed first, prefixed in the end.

    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.
  • photo

    Thiemo

    Monday, April 30, 2012

    About what you call a "situation": I really want to understand that "situation". Please show us a list of sites that are actually broken because of a missing border-radius, box-shadow, transform or transition (with "broken" meaning "can't be used" or at least "looks broken even for somebody who never saw the site in WebKit").
  • photo

    Thiemo

    Monday, April 30, 2012

    OK, let's focus on whats important: "transform" and "transition" is not a problem since its prefixed anyway. But you already dropped all prefixes from "border-radius" and "box-shadow". This change will prefix these properties again. This will break existing standard-compliant websites that rely on the non-prefixed properties.
  • photo

    Adrian Roselli

    Monday, April 30, 2012

    @Thiemo, I have seen a few sites that are "broken" thanks to poor coding, but the one that stood out to me is http://webs.com. I included a screen shot of the home page in Opera vs. Safari in my own rant at http://blog.adrianroselli.com/2012/04/dont-blame-opera-blame-devs.html. Sadly, that's the only example I have handy, but it's the most common error I have seen (white text on a missing gradient).
  • photo

    Thiemo

    Wednesday, May 2, 2012

    Fixing "a few" sites is a job for the browser.js and no reason to mess around with a web standard. Also, there is an other very, very easy solution: Drop the -o- prefix and make Opera aware of linear-gradient. This will fix sites like webs.com. Don't tell me you can't do this till the spec is a W3C recommendation. This is not different from aliasing "-webkit-linear-gradient". Alias "linear-gradient" instead.
  • photo

    YongShun

    Thursday, May 3, 2012

    Disappointment to web developers who insists on using webkit css instead of the standards
  • photo

    Frans

    Monday, May 7, 2012

    @Adrian
    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.
  • photo

    Patrick H. Lauke

    Thursday, June 14, 2012

    Thiemo, regarding the broken behaviour in your example pages: as the above-mentioned properties have been aliased, it's simply a matter of cascade and the order in which the rules are present. Last one wins. Possibly not ideal (well, the whole situation isn't), but at least it is predictable and consistent.
  • photo

    JanGen

    Thursday, June 21, 2012

    I also don't like Opera supporting webkit prefixes. It's simple, like Thiemo explained.
    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.
  • photo

    Thiemo

    Friday, July 6, 2012

    I can't belief you are putting this broken stuff in the current 12.50 preview without answering any of the questions. What about using the browser.js? Don't tell us it would be "to big". Fix the sites that need to be fixed but don't mess around with a web standard. What about simply dropping all -o- prefixes instead of prefixing properties *again* that aren't prefixed currently? What about making -o- properties higher precedence? Don't tell us this would "break the cascade". What you do is worse: -webkit- properties were *never* be intended to be part of the cascade in the Presto rendering engine. Don't tell us the vendor prefixes are not made to target specific rendering engines. It doesn't make any sense to introduce vendor specific properties and *later*, when we all use them tell us these vendor specific properties were never be intended to be vendor specific. What the heck? I want a browser that acts like the browser I love. I don't need *another* browser that acts like Webkit. I'm begging you please, please find another solution. There *are* other solutions. At least make this -webkit- rubbish lower precedence (lower than -o- and also lower that the unprefixed properties). From all I know this would be the easiest solution to not break existing sites.
No new comments accepted.