Saturday 11 February 2012

CSS Vendor Prefixes: Another Storm in Another Teacup - or a Rip in the Fabric of Space-Time?


Is the current concern over vendor prefixes in CSS something that can be solved by tweaking the current mechanisms and asking everyone to play fair in the interests of the "Open Web", or is it a sign of something darker, a the sign of something deeply broken, that is only going to get worse as time goes on? I think there's a danger of the latter, and I think that this current discussion is indeed indicative of the deeper problems that exist.

The Current CSS Vendor Prefix Kerfuffle

But first: before I wring my cassandra like hands, I'm late-ish to the party in writing about this and you may have no idea what I'm talking about.
The dominance of Apple and Google mobile browsers is leading to a situation that's even worse for Web programming than the former dominance of Internet Explorer, a standards group leader warned today.
Reported CNET based on a post by Daniel Glazman, chair of the CSS WG, asking everyone to change their Web sites and no longer use the -webkit- prefix.

Lots of people have posted on this, and I thought that before ploughing in with an opinion of my own, I'd do a little research as to what the CSS Working Group says about vendor prefixes. I'd always thought that the vendor prefix was a crude namespacing mechanism to allow proprietary extensions to CSS. 

There are lots of good reasons for having a non-standardised extensibility mechanism, of course. If I was making a browser intended for operation at the depths of the ocean I can imagine a number of proprietary features that I wouldn't expect to be standardised. That seems fine. 

Equally, in a browser that operates using an operating system that has specific user interface metaphors, an author might want to control the properties of the rendering of user interface artefacts in that environment only. -iOS-triangular-button-pointyness could possibly be the right way to control the pointedness of a triangular button under iOS. 

Vendor Prefixes for Experimentation

The thing is that in addition to these use cases, the CSS Working Group recommends using vendor prefixes for implementation of experimental features which are under consideration for standardisation. 

Let's look at what the CSS working group says, in "Cascading Style Sheets (CSS) Snapshot 2010 W3C Working Group Note 12 May 2011" [http://www.w3.org/TR/CSS/]:

3.3. Experimental Implementations 
To avoid clashes with future CSS features, the CSS2.1 specification reserves a prefixed syntax for proprietary and experimental extensions to CSS. 
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. This avoids incompatibilities with future changes in the draft.
[my emphasis]

Here's what the "prefixed syntax" link says [http://www.w3.org/TR/CSS21/syndata.html#vendor-keywords]:

4.1.2.1 Vendor-specific extensions 
In CSS, identifiers may begin with '-' (dash) or '_' (underscore). Keywords and property names beginning with -' or '_' are reserved for vendor-specific extensions. Such vendor-specific extensions should have one of the following formats: 
'-' + vendor identifier + '-' + meaningful name
'_' + vendor identifier + '-' + meaningful name
... 
Authors should avoid vendor-specific extensions
A few notes on the above.
  1. It would seem that in order to test the viability of features in upcoming standards (Recommendations, whatever) you have to get authors to use them, and you shouldn't name them the same as anyone else, you should name them according to a proprietary extension scheme. That's very silly. As ppk points out in his post, if you are going to do this then they should be called -experimental-foo (or something) by everyone. 
  2. You may also have noted that there is an inherent contradiction between recommending vendors to prefix experimental features and recommending authors not to use vendor specific extensions. 
  3. It doesn't look to me as though it was intended in CSS 2.1 (or 2) that vendor prefixes should be used for not-yet-standardised features - i.e. the text in the quotation above 4.1.2.1 makes no mention of experimentation. Is this a novel interpretation?
  4. The piece of the WG Note that says "avoids incompatibilities" is almost funny, in the current circumstances. Seems to me that in using prefixes, although they are not avoiding but guaranteeing future incompatibility, vendors are only doing what they are asked to do.
  5. Coming back to the  -experimental-foo suggestion - caveat emptor. I'm reminded of lengthy discussions in the course of writing "W3C Content Transformation Guidelines" about the idiom of X- prefixed HTTP headers, also widely understood to be for extensions and experimental features. Once in the wild these things stay in the wild.
But there is no such thing as "experimentation"

The browsers in which these experimental features are unleashed are not called experimental browsers. Usually they are not even beta versions, let alone experimental. Let's be clear, then, that reality says that once you unleash an experimental feature you have then littered the Web environment with some kind of requirement for ongoing support. Authors that have used the feature are unlikely ever to change it. Users of any particular version of a browser may not ever update it, they may not know how to, and in certain common situations are not even able to do so even if they wanted to. 

Daniel Glazman's note asking Web Authors to update their sites to use the non-prefixed version conjures up a picture in my mind of Web site owners getting out their editors, grepping the entire contents of all their sites and doing a replace operation. Simple. Well, possibly a bit unrealistic. I mean, first of all, you'd want to leave the prefixed version in, wouldn't you. Otherwise your site is going to break for some browsers it works in today. 

Secondly, and probably more importantly, I find it very hard to imagine that the majority of Web sites are built that way at all. I find it very hard to imagine that anything but a very small number of Web sites are operated by anyone who has the slightest clue what CSS is. Let alone a vendor prefix. I'm guessing that almost all of them rely on libraries, frameworks, external vendor support - whatever it is, it is unlikely to be a tame developer sitting waiting to do a grep. i.e. it's not going to happen.

Standards Junk

The experimental features are in the wild, the genie is out of the bottle. It seems wholly unsurprising that vendors will want to implement them. Actually they may not just "want" they need to copy each other's prefixes for interoperability purposes. The process guarantees a legacy problem, the standards equivalent of space junk. 

The outcome of all this is that all sites, in theory, need to include all variants of the name of every property that has been through this process. All browsers need to support every variant too - and not only as synonyms of each other, they need to support the browser specific quirks too.

And all this has the intention of avoiding future incompatibilities. A standardisation process that guarantees the need to use non-standard extensions truly needs to be reconsidered.

What's Really Wrong

The fact that experimental features have got mixed up with browser extensions is a problem. 

However, there's other, rather more difficult stuff that I suggest needs fixing.  The most important, I think, is that basic mechanisms for version negotiation and any kind of feature detection are missing. 

The assumption, I think, is that any Web page and its representational variants are somehow some unitary whole. By using precedence, the cascade and some @media at-rules in the CSS the client somehow figures out what it is supposed to do. But this is a problem since a single page may have a very wide variety of representations, depending on the version of a browser and its context. Is it really practical to think that an indefinite range of delivery contexts, feature support, bug workarounds and so on can really be encoded into a single CSS script?

There's no possibility within CSS to express "if you support x feature do all this, if not do something else" - up to a point, you might be able to do that by browser sniffing at the server, CSS could help, but doesn't - since there is no way within the scope of CSS for a server to know what level of CSS the browser supports, which of the optional parts at any level are supported and what modules are available.

CSS maintainability is terrible. SASS etc go some way to improve that by allowing expressions and by allowing the explicit coupling of property values (through assignment to a variable, or whatever).

With the advent of webkit and its life-saving CSS inspector it has actually been possible to see the effect of the cascades and so on and actually do some debugging. This is a relatively recent development in the life of CSS though. And we could probably do with some more authoring tools to make the creation of CSS a deal more foolproof than it is.

There's some other stuff in relation to CSS too, some of which I probably should know the answer to, but don't, some of which have been discussed to death and some of which are a bit whimsical.

For example, why is the syntax of CSS so hokey? Given silent failure and recovery of CSS and silent failure and recovery of HTML(5) are the rules aligned? Should they be? Why are CSS selectors and XPath selectors so different? Aren't they in fact doing the same job? The list goes on ...

Finally and Incidentally

This isn't really very important, but in the course of my looking into what the history of the prefixed syntax, I noticed that CSS Level 2 contains [at http://www.w3.org/TR/CSS2/syndata.html]  the following
4.1.1 Tokenization

All levels of CSS — level 1, level 2, and any future levels — use the same core syntax.
 However, that doesn't appear to be the case, since CSS 2 allows prefixed syntax:
ident [-]?{nmstart}{nmchar}*
nmstart [_a-z]|{nonascii}|{escape}
nmchar [_a-z0-9-]|{nonascii}|{escape}
whereas CSS 1 [http://www.w3.org/TR/REC-CSS1/] doesn't:
ident {nmstrt}{nmchar}*
nmstrt [a-z]|{latin1}|{escape}
nmchar [-a-z0-9]|{latin1}|{escape}
Ho Hum.

No comments:

Post a Comment