CSS and style

Cascading Style Sheets and other exotic stylistic animals

Entries feed - Comments feed

Saturday 16 January 2016

Ebook pagination and CSS

Let's suppose you have a rather long document, for instance a book chapter, and you want to render it in your browser à la iBooks/Kindle. That's rather easy with just a dash of CSS:

body {
height: calc(100vh - 24px);
column-width: 45vw;
overflow: hidden;
margin-left: calc(-50vw * attr(currentpage integer));

Yes, yes, I know that no browser implements that attr()extended syntax. So put an inline style on your body for margin-left: calc(-50vw * <n>) where <n> is the page number you want minus 1.

Then add the fixed positioned controls you need to let user change page, plus gesture detection. Add a transition on margin-left to make it nicer. Done. Works perfectly in Firefox, Safari, Chrome and Opera. I don't have a Windows box handy so I can't test on Edge.

Wednesday 13 January 2016

CSS Prefixed and unprefixed properties

I used to be quite a heavy user of Peter Beverloo's list of CSS properties, indicating all prefixed versions, but he stopped maintaining it a while ago, unfortunately. So I wrote my own, because I still need such data for BlueGriffon... In case you also need it, it's available from http://disruptive-innovations.com/zoo/cssproperties/ and is automatically refreshed from Gecko, WebKit and Blink sources on a daily basis.

Friday 4 September 2015

ParisWeb 2015

Les inscriptions à ParisWeb, la meilleure conf du secteur depuis 2006, c'est maintenant !

Thursday 30 July 2015

CSS Vendor Prefixes

I have read everything and its contrary about CSS vendor prefixes in the last 48 hours. Twitter, blogs, Facebook are full of messages or articles about what are or are supposed to be CSS vendor prefixes. These opinions are often given by people who were not members of the CSS Working Group when we decided to launch vendor prefixes. These opinions are too often partly or even entirely wrong so let me give you my own perspective (and history) about them. This article is with my CSS Co-chairman's hat off, I'm only an old CSS WG member in the following lines...

  • CSS Vendor Prefixes as we know them were proposed by Mike Wexler from Adobe in September 1998 to allow browser vendors to ship proprietary extensions to CSS.

    In order to allow vendors to add private properties using the CSS syntax and avoid collisions with future CSS versions, we need to define a convention for private properties. Here is my proposal (slightly different than was talked about at the meeting). Any vendors that defines a property that is not specified in this spec must put a prefix on it. That prefix must start with a '-', followed by a vendor specific abbreviation, and another '-'. All property names that DO NOT start with a '-' are RESERVED for using by the CSS working group.

  • One of the largest shippers of prefixed properties at that time was Microsoft that introduced literally dozens of such properties in Microsoft Office.
  • The CSS Working Group slowly evolved from that to « vendor prefixes indicate proprietary features OR experimental features under discussion in the CSS Working Group ». In the latter case, the vendor prefixes were supposed to be removed when the spec stabilized enough to allow it, i.e. reaching an official Call for Implementation.
  • Unfortunately, some prefixed « experimental features » were so immensely useful to CSS authors that they spread at fast pace on the Web, even if the CSS authors were instructed not to use them. CSS Gradients (a feature we originally rejected: « Gradients are an example. We don't want to have to do this in CSS. It's only a matter of time before someone wants three colors, or a radial gradient, etc. ») are the perfect example of that. At some point in the past, my own editor BlueGriffon had to output several different versions of CSS gradients to accomodate the various implementation states available in the wild (WebKit, I'm looking at you...).
  • Unfortunately, some of those prefixed properties took a lot, really a lot, of time to reach a stable state in a Standard and everyone started relying on prefixed properties in production web sites...
  • Unfortunately again, some vendors did not apply the rules they decided themselves: since the prefixed version of some properties was so widely used, they maintained them with their early implementation and syntax in parallel to a "more modern" implementation matching, or not, what was in the Working Draft at that time.
  • We ended up just a few years ago in a situation where prefixed proprerties were so widely used they started being harmful to the Web. The indredible growth of first WebKit and then Chrome triggered a massive adoption of prefixed properties by CSS authors, up to the point other vendors seriously considered implementing themselves the -webkit- prefix or at least simulating it.

Vendor prefixes were not a complete failure. They allowed the release to the masses of innovative products and the deep adoption of HTML and CSS in products that were not originally made for Web Standards (like Microsoft Office). They allowed to ship experimental features and gather priceless feedback from our users, CSS Authors. But they failed for two main reasons:

  1. The CSS Working Group - and the Group is really made only of its Members, the vendors - took faaaar too much time to standardize critical features that saw immediate massive adoption.
  2. Some vendors did not update nor "retire" experimental features when they had to do it, ditching themselves the rules they originally agreed on.

From that perspective, putting experimental features behind a flag that is by default "off" in browsers is a much better option. It's not perfect though. I'm still under the impression the standardization process becomes considerably harder when such a flag is "turned on" in a major browser before the spec becomes a Proposed Recommendation. A Standardization process is not a straight line, and even at the latest stages of standardization of a given specification, issues can arise and trigger more work and then a delay or even important technical changes. Even at PR stage, a spec can be formally objected or face an IPR issue delaying it. As CSS matures, we increasingly deal with more and more complex features and issues, and it's hard to predict when a feature will be ready for shipping. But we still need to gather feedback, we still need to "turn flags on" at some point to get real-life feedback from CSS Authors. Unfortunately, you can't easily remove things from the Web. Breaking millions of web sites to "retire" an experimental feature is still a difficult choice...

Flagged properties have another issue: they don't solve the problem of proprietary extensions to CSS that become mainstream. If a given vendor implements for its own usage a proprietary feature that is so important to them, internally, they have to "unflag" it, you can be sure some users will start using it if they can. The spread of such a feature remains a problem, because it changes the delicate balance of a World Wide Web that should be readable and usable from anywhere, with any platform, with any browser.

I think the solution is in the hands of browser vendors: they have to consider that experimental features are experimental whetever their spread in the wild. They don't have to care about the web sites they will break if they change, update or even ditch an experimental or proprietary feature. We have heard too many times the message « sorry, can't remove it, it spread too much ». It's a bad signal because it clearly tells CSS Authors experimental features are reliable because they will stay forever as they are. They also have to work faster and avoid letting an experimental feature alive for more than two years. That requires taking the following hard decisions:

  • if a feature does not stabilize in two years' time, that's probably because it's not ready or too hard to implement, or not strategic at that moment, or that the production of a Test Suite is a too large effort, or whatever. It has then to be dropped or postponed.
  • Tests are painful and time-consuming. But testing is one of the mandatory steps of our Standardization process. We should "postpone" specs that can't get a Test Suite to move along the REC track in a reasonable time. That implies removing the experimental feature from browsers, or at least turning the flag they live behind off again. It's a hard and painful decision, but it's a reasonable one given all I said above and the danger of letting an experimenal feature spread.

Monday 29 June 2015

CSS Working Group's future

Hello everyone.

Back in March 2008, I was extremely happy to announce my appointment as Co-chairman of the CSS Working Group. Seven years and a half later, it's time to move on. There are three main reasons to that change, that my co-chair Peter and I triggered ourselves with W3C Management's agreement:

  1. We never expected to stay in that role 7.5 years. Chris Lilley chaired the CSS Working Group 1712 days from January 1997 (IIRC) to 2001-oct-10 and that was at that time the longest continuous chairing in W3C's history. Bert Bos chaired it 2337 days from 2001-oct-11 to 2008-mar-05. Peter and I started co-chairing it on 2008-mar-06 and it will end at TPAC 2015. That's 2790 days so 7 years 7 months and 20 days! I'm not even sure those 2790 days hold a record, Steven Pemberton probably chaired longer. But it remains that our original mission to make the WG survive and flourish is accomplished, and we now need fresher blood. Stability is good, but smart evolution and innovation are better.
  2. Co-chairing a large, highly visible Working Group like the CSS Working Group is not a burden, far from it. But it's not a light task either. We start feeling the need for a break.
  3. There were good candidates for the role, unanimously respected in the Working Group.

So the time has come. The new co-chairs, Rossen Atanassov from Microsoft and Alan Stearns from Adobe, will take over during the Plenary Meeting of the W3C held in Sapporo, japan, at the end of October and that is A Good Thing™. You'll find below a copy of my message to W3C.

To all the people I've been in touch with while holding my co-chair's hat: thank you, sincerely and deeply. You, the community around CSS, made everything possible.

Yours truly.

Dear Tim, fellow ACs, fellow Chairs, W3C Staff, CSS WG Members,

After seven years and a half, it's time for me to pass the torch of the CSS Working Group's co-chairmanship. 7.5 years is a lot and fresh blood will bring fresh perspectives and new chairing habits. At a time the W3C revamps its activities and WGs, the CSS Working Group cannot stay entirely outside of that change even if its structure, scope and culture are retained. Peter and I decided it was time to move on and, with W3M's agreement, look for new co-chairs.

I am really happy to leave the Group in Alan's and Rossen's smart and talented hands, I'm sure they will be great co-chairs and I would like to congratulate and thank them for accepting to take over. I will of course help the new co-chairs on request for a smooth and easy transition, and I will stay in the CSS WG as a regular Member.

I'd like to deeply thank Tim for appointing me back in 2008, still one of the largest surprises of my career!

I also wish to warmly thank my good friends Chris Lilley, Bert Bos and Philippe Le Hégaret from W3C Staff for their crucial daily support during all these years. Thank you Ralph for the countless transition calls! I hope the CSS WG still holds the record for the shortest positive transition call!

And of course nothing would have been possible without all the members of the CSS Working Group, who tolerated me for so long and accepted the changes we implemented in 2008, and all our partners in the W3C (in particular the SVG WG) or even outside of it, so thank you all. The Membership of the CSS WG is a powerful engine and, as I often say, us co-chairs have only been a drop of lubricant allowing that engine to run a little bit better, smoother and without too much abrasion.

Last but not least, deep thanks to my co-chair and old friend Peter Linss for these great years; I accepted that co-chair's role to partner with Peter and enjoyed every minute of it. A long ride but such a good one!

I am confident the CSS Working Group is and will remain a strong and productive Group, with an important local culture. The CSS Working Group has both style and class (pun intended), and it has been an honour to co-chair it.

Thank you.


Monday 2 March 2015

Adobe Edge Reflow anyone?

Edge ReflowI received this morning a message from the Adobe Edge Reflow prerelease forum that triggered my interest. I must admit I did not really follow what happened there during the last twelve months for many various reasons... But this morning, it was different. In short, the author had questions about the fate of Edge Reflow, in particular because of the deep silence of that forum...

Adobe announced Edge Reflow in Q3 2012 I think. It followed the announcement of Edge Code a while ago. Reflow was aimed at visual responsive design in a new, cool, interactive desktop application with mobile and photoshop links. The first public preview was announced in February 2013 and a small community of testers and contributors gathered around the Adobe prerelease fora. Between January 2013 and now, roughly 1300 messages were sent there.

Reflow is a html5/JS app turned into a desktop application through the magic of CEF. It has a very cool and powerful UI, superior management of simple Media Queries, excellent management of colors, backgrounds, layers, magnetic grids and more. All in all, a very promising application for Web Authoring.

But the last available build of Reflow, again through the prerelease web site, is only a 0.57.17154 and it is now 8 months old. After 2 years and a half, Reflow is still not here and there are reasons to worry.

First, the team (the About dialog lists more than 20 names...) seems to have vanished and almost nothing new has been contributed/posted to Reflow in the last six to eight months.

Second, the application still suffers from things I identified as rather severe issues early on: the whole box model of the application is based on CSS floats and is then not in line with what modern web designers are looking for. Eh, it's not even using absolute positioning... It also means it's going to be rather complicated to adapt it to grids and flexbox, not even mentioning Regions...

Reflow also made the choice to generate Web pages instead of editing Web pages... It means projects are saved in a proprietary format and only exported to html and CSS. It's impossible to take an existing Web page and open it in Reflow to edit it. In a world of Web Design that sees authors use heterogeneous environments, I considered that as a fatal mistake. I know - trust me, I perfectly know - that making html the pivot format of Reflow would have implied some major love and a lot, really a lot of work. But not doing it meant that Edge Reflow had to be at the very beginning of the editorial chain, and that seemed to me an unbearable market restriction.

Then there was the backwards compatibility issue. Simply put, how does one migrate Dreamweaver templates to Reflow? Short answer, you can't...

I suspect Edge Reflow is now at least on hold, more probably stopped. More than 2 years and still no 1.0 on such an application that should have seen a 1.0beta after six to eight months is not a good sign anyway. After Edge Code that became Brackets in november 2014, that raises a lot of question on the Edge concept and product line. Edge Animate seems to be still maintained at Adobe (there's our old Netscape friend Kin Blas in the list of credits) but I would not be surprised if the name is changed in the future.

Too bad. I was, in the beginning, really excited by Edge Reflow. I suspect we won't hear about it again.

Sunday 8 February 2015

CSS Parser and Tokenizer API

The first time I mentioned the need to reach the internal CSS parser of a rendering engine from JavaScript was 17 years ago during the CSS WG meeting I hosted at Électricité de France in 1998, during a corridor discussion. All the people around said it was out of question. Then I put it back on the table in 2002, with little success again. Today, I was actioned by the CSS WG and the TAG in the Houdini Task Force to start editing a new document (with Tab Atkins, Shane Stevens and Brian Kardell) called CSS Parser and Tokenizer API. It does not say it's going to be accepted or anything, but at least it went beyond the 5 minutes chat and rebuttal. I am extremely happy and proud :-) If we succeed making it happen, this is going to be a game-changer for a lot of web applications!!!

Thursday 18 December 2014

Bulgaria Web Summit

I will be speaking at the Bulgaria Web Summit 2015 in Sofia, Bulgaria, 18th of april.

Wednesday 19 March 2014

A better CSS OM for parsed values

A large part of the current CSS Object Model sucks. More specifically, the CSSValue, CSSPrimitiveValue, CSSValueList, RGBColor, Rect and Counter interfaces are so poorly designed they're not implemented. I just tried to implement them for a project of mine and I must say the model is so weak and incoherent it cannot be implemented as is.

I have then tried to refine what's in the 2000-nov-13 spec of DOM Level 2 Style to reach something workable. I am NOT saying this has to be done or implemented. Call it a mental exercise I did just for fun, w/o caring about performance.

Let's first look at what's wrong:

Interface CSSValue

      interface CSSValue {
        // UnitTypes
        const unsigned short      CSS_INHERIT                    = 0;
        const unsigned short      CSS_PRIMITIVE_VALUE            = 1;
        const unsigned short      CSS_VALUE_LIST                 = 2;
        const unsigned short      CSS_CUSTOM                     = 3;
                 attribute DOMString        cssText;
                                              // raises(DOMException) on setting
        readonly attribute unsigned short   cssValueType;

"inherit" is here considered as a special identifier despite of the fact a CSSPrimitiveValue can be a CSS_IDENT. There is no UnitType for "initial". A CSS_CUSTOM is, according to the spec, a "custom value"; but a custom value still has to be valid per CSS syntax so it should be representable with CSS_VALUE_LISTs and CSS_VALUEs.

Interface CSSValueList

interface CSSValueList : CSSValue {
  readonly attribute unsigned long    length;
  CSSValue           item(in unsigned long index);

All in all, this one is simple and should be quite ok. But one thing is missing: a property can accept a comma-separated list of whitespace-separated values. The current CSSValueList cannot express if the serialization of a CSSValueList should be whitespace- or comma-separated.

Interface CSSPrimitiveValue

interface CSSPrimitiveValue : CSSValue {

  // UnitTypes
  const unsigned short      CSS_UNKNOWN                    = 0;
  const unsigned short      CSS_NUMBER                     = 1;
  const unsigned short      CSS_PERCENTAGE                 = 2;
  const unsigned short      CSS_EMS                        = 3;
  const unsigned short      CSS_EXS                        = 4;
  const unsigned short      CSS_PX                         = 5;
  const unsigned short      CSS_CM                         = 6;
  const unsigned short      CSS_MM                         = 7;
  const unsigned short      CSS_IN                         = 8;
  const unsigned short      CSS_PT                         = 9;
  const unsigned short      CSS_PC                         = 10;
  const unsigned short      CSS_DEG                        = 11;
  const unsigned short      CSS_RAD                        = 12;
  const unsigned short      CSS_GRAD                       = 13;
  const unsigned short      CSS_MS                         = 14;
  const unsigned short      CSS_S                          = 15;
  const unsigned short      CSS_HZ                         = 16;
  const unsigned short      CSS_KHZ                        = 17;
  const unsigned short      CSS_DIMENSION                  = 18;
  const unsigned short      CSS_STRING                     = 19;
  const unsigned short      CSS_URI                        = 20;
  const unsigned short      CSS_IDENT                      = 21;
  const unsigned short      CSS_ATTR                       = 22;
  const unsigned short      CSS_COUNTER                    = 23;
  const unsigned short      CSS_RECT                       = 24;
  const unsigned short      CSS_RGBCOLOR                   = 25;

  readonly attribute unsigned short   primitiveType;
  void               setFloatValue(in unsigned short unitType, 
                                   in float floatValue)
  float              getFloatValue(in unsigned short unitType)
  void               setStringValue(in unsigned short stringType, 
                                    in DOMString stringValue)
  DOMString          getStringValue()
  Counter            getCounterValue()
  Rect               getRectValue()
  RGBColor           getRGBColorValue()

This is so completely crazy I don't know where to start...

  • CSS_UNKNOWN is supposed to represent a "value that is not a recognized CSS2 value". Then it should be thrown away by the parser as invalid and never reach the OM, right?
  • the list of units is long and not easily extensible
  • attr(), counter(), counters(), rect() and the more recent gradients or var() calls are all functions; adding a new setter and a new getter for each new type is overkill
  • attr() was extended by recent specs and can now take more than one argument. The above does not allow to individually modify those arguments.
  • "initial" and "inherit" are, as I already said above, covered by both CSSValue and CSS_IDENT here
  • let's suppose we have a CSSValue that is a CSSPrimitiveValue. Setting its cssText to "10px 10px" will then trigger an exception since a CSSPrimitiveValue cannot transmute magically into a CSSValueList...
  • I love how the spec prose says setStringValue() has "No Parameters"...

Interface Rect

interface Rect {
  readonly attribute CSSPrimitiveValue  top;
  readonly attribute CSSPrimitiveValue  right;
  readonly attribute CSSPrimitiveValue  bottom;
  readonly attribute CSSPrimitiveValue  left;

This looks and smells like a CSSValueList far too much.

Interface RGBColor

interface RGBColor {
  readonly attribute CSSPrimitiveValue  red;
  readonly attribute CSSPrimitiveValue  green;
  readonly attribute CSSPrimitiveValue  blue;

This cannot represent rgba(), hsl() and hsla() colors. We also have to use three CSSPrimitiveValue for the three color components because they can be a percentage or an integer...

Interface Counter

interface Counter {
  readonly attribute DOMString        identifier;
  readonly attribute DOMString        listStyle;
  readonly attribute DOMString        separator;

Again, something is missing here: nothing says if it's supposed to be a counter() or a counters() value. And no, the separator could not do the trick since it can be the empty string.


To have a better OM for Values, i.e. an extensible OM that allows an application to deal with parsed values of all kinds, we need to change of perspective. First, the list of reserved idents, the list of units and the list of functions are not extensible. Secondly, we have cast issues between PrimitiveValues and ValueLists and we need a single interface. We can deal with all the issues with a single CSSValue interface:

New interface CSSValue

interface CSSValue {

  // ValueTypes
  const unsigned short      CSS_SYMBOL                     = 0;
  const unsigned short      CSS_NUMBER                     = 1;
  const unsigned short      CSS_UNIT                       = 2;
  const unsigned short      CSS_STRING                     = 3;
  const unsigned short      CSS_URI                        = 4;
  const unsigned short      CSS_IDENT                      = 5;
const unsigned short CSS_VALUE_LIST = 6; readonly attribute unsigned short type; attribute boolean commaSeparated;
readonly attribute unsigned long length;
CSSValue item(in unsigned long index);

void setFloatValue(in float floatValue) raises(DOMException); float getFloatValue() raises(DOMException);
void setStringValue(in DOMString stringValue) raises(DOMException); DOMString getStringValue() raises(DOMException); };

Definition group ValueTypes

An integer indicating the type of the Value

The value is a single character than cannot be interpreted otherwise. For instance the / character in the font shorthand property. The value can be obtained by the getStringValue() and set by the setStringValue() method.
The value is a simple number. The value can be obtained by using the getFloatValue() method and set through by setFloatValue() method.
The value is a number followed by a unit. The number part of the value can be obtained by using the getFloatValue() method and set through by setFloatValue() method. The unit part of the value can be obtained by using the getUnit() method and set through by setUnit() method
The value is a string. The value can be obtained by the getStringValue() and set by the setStringValue() method.
The value is a URI. The parameter of the url() function can be obtained by the getStringValue() and set by the setStringValue() method.
The value is a CSS identifier. The value can be obtained by the getStringValue() and set by the setStringValue() method.
The value is a list of values or a function. It is a function if the getStringValue() method does not reply the empty string. The list of values is whitespace-separated if the commaSeparated attribute is false and comma-separated otherwise.


type of type unsigned short, readonly
The type of the value as defined by the constants specified above.
commaSeparated of type boolean
The separation type of the list of values. Meaningful only if the type attribute is CSS_VALUE_LIST. The list is whitespace-separated if the attribute is false and comma-separated otherwise.
length of type unsigned long, readonly
The number of CSSValue in the list. The range of valid values of the indices is 0 to length-1 inclusive.
INVALID_ACCESS_ERR: Raised if the CSS value is a not a CSS_VALUE_LIST.


Retrieves the value of a CSS_NUMBER or the number part of the value of a CSS_UNIT. If this CSS value is not a CSS_NUMBER or a CSS_UNIT, a DOMException is raised.
Return Value
float The float value of this CSS_NUMBER or CSS_UNIT
INVALID_ACCESS_ERR: Raised if the CSS value isn't a CSS_NUMBER nor a CSS_UNIT.
For a CSS_SYMBOL, retrieves the single character used as a symbol.
For a CSS_STRING, retrieves the string. Enclosing quotes or double-quotes are NOT included.
For a CSS_UNIT, retrieves the unit of the value.
For a CSS_URI, retrieves the argument of the url(...) notation. Enclosing quotes or double-quotes are NOT includedt.
For a CSS_IDENT, retrieves the identifier.
For a CSS_VALUE_LIST and if that list of values is passed as the parameters of a function, retrieves the function name. Retrieves the empty string otherwise.
For a CSS_NUMBER and CSS_UNIT, a DOMException is raised.
No Parameters
Return Value
DOMString The float value of this CSS_NUMBER or CSS_UNIT
INVALID_ACCESS_ERR: Raised if the CSS value is a CSS_NUMBER or a CSS_UNIT.
For a CSS_VALUE_LIST, Used to retrieve a CSSValue by ordinal index. The order in this collection represents the order of thevalues in the CSS style property. If index is greater than or equal to the number of values in the list, this returnsnull.
For all other value types, a DOMException is raised.
index of type unsigned long: index into the collection.
Return value
CSSValue The CSSValue at the index position in the CSSValueList, or null if that is not a valid index.
INVALID_ACCESS_ERR: Raised if the CSS value is a not a CSS_VALUE_LIST.
Sets the value of a CSS_NUMBER or the number part of the value of a CSS_UNIT. If this CSS value is not a CSS_NUMBER or a CSS_UNIT, a DOMException is raised.
floatValue of type float;
No Return Value
INVALID_ACCESS_ERR: Raised if the CSS value isn't a CSS_NUMBER nor a CSS_UNIT or if the attached property doesn't support the float value or the unit type.
NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly.
For a CSS_SYMBOL, sets the single character used as a symbol.
For a CSS_STRING, sets the string.
For a CSS_UNIT, sets the unit of the value.
For a CSS_URI, sets the argument of the url(...) notation.
For a CSS_IDENT, sets the identifier.
For a CSS_VALUE_LIST and if the parameter is not the empty string, make the list of values become a function and sets the function name. Make the list become a plain list of values if the parameter is the empty string.
For a CSS_NUMBER and CSS_UNIT, a DOMException is raised.
stringValue of type DOMString
No Return Value
INVALID_ACCESS_ERR: Raised if the CSS value is a CSS_NUMBER or a CSS_UNIT, if the type of the value is CSS_SYMBOL and the string can be parsed as an other type of value, if the type of the value is CSS_UNIT and the string is not a valid CSS unit, if the type of the value is CSS_URI and the string is not a valid URI, if the type of the value is CSS_IDENT and the string is not a valid CSS identifier, if the type of the value is CSS_VALUE_LIST and the string is not a valid CSS identifier or the empty string.
NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly.


The above should be enough to describe any CSS value, specified or computed. The model will become a bit complex for complex values but it ensures any web application can have access to parsed values, deal with their types and modify them. Let's take an example:

background-image: linear-gradient(to bottom, yellow 0%, blue 100%), url(foo.png);

This will result in the following OM (click on the image to enlarge it):

OM example

Again, I'm not saying the above is the thing to do or implement. It can certainly be improved, for instance for colors. A totally different perspective is also perfectly possible. I am only saying that making a better CSS OM allowing a full representation of parsed values in stylesheets and computed values is feasible. I hope the CSS OM will offer such power in the future.

UPDATE: the new CSSValue interface above lacks one thing, the ubiquitous cssText for parsing and serialization. Sorry for that.

Friday 31 January 2014

CSS Regions

If there is one and only article you should read about CSS Regions, that's this one. And the conclusion is quite clear and I agree with it:

CSS Regions give us the ability to do a lot of things that are otherwise not possible without them

Sunday 13 January 2013

CSS Paged Media and GCPM

I wrote a quite long article about the current CSS Paged Media and Generated Content for Paged Media specs/proposals and why they're outdated and are not enough. You can find it here,  on www-style.

Friday 17 August 2012

CSS Variables, why we drop the $foo notation

CSS Variables... A major request from the Web Authors' community since 1998...

Dave Hyatt and I shaped the first concrete public proposal in 2008 but the CSS Working Group could not reach an agreement about it. Variables, constants, mutable constants, OM or no OM, we had endless "religious" discussions about that and Hyatt finally removed his implementation from WebKit.

Then Tab Atkins made a breakthrough last february proposing a much better CSS integration, a model that fits nicely with what we already have. But then we had a problem with the $foo syntax everyone was asking for. Let me explain...

First, the proposed spec is NOT about variables and I seriously wonder if we should not change the title of the document. You may call the feature it introduces "variables" but at the deeper level, that's not about variables. That about Inherited User-Defined Properties. Don't take that as some political correctness or a blurb hiding the reality of the feature. The spec is really about letting you define your own properties and reaching their cascaded values. For instance:

div > p {
var-myprop: 1;

p {
var-myprop: 2;

In the above case, what will be the value of var(myprop) in a p contained into a div? Right, it will be 1 because the first rule has a higher specificity than the second one... Clearly, these beasts are not variables in the usual acceptance of the term.

Second, how are we going to use the values specified that way? We considered data(myprop), var(myprop) and $myprop. And despite of all the arguments expressed by the community in favor of the latter, the CSS WG decided during its recent San Diego face-to-face meeting to not follow the $foo path: $foo for the getter is too similar to a programming language, leading to confusion. The $ notation is used by preprocessors and script-based toolkits all over the place, it deeply conveys a notion of "programming language variable" or "preprocessor macro". And that's not what this spec is about since the feature introduced by the current spec shows important restrictions a variable or macro would not show:

  1. the value must be a set of valid CSS tokens; don't think of a preprocessor, don't dream of a partial string replacement. I repeat: a set of valid CSS tokens.
  2. you can't use the getter anywhere in CSS Stylesheets. You can use it only on the right-hand side of declarations (in other tems, after the colon in a '<property> : <values>' style declaration).
  3. we need an optional second argument to the getter giving a fallback value if the user-defined property is not set at all on the element.

Before shouting, don't misunderstand us: we clearly see the simplicity, readability and maintainability of the $foo syntax and we perfectly understand why the community prefers it. Being ourselves coders and implementors, we're used to manipulate $-based notations. But running that path implies too much confusion about our feature, will then lead to errors in live stylesheets, impacts existing CSS preprocessors that will have to change their own syntax to avoid collisions with ours, and will block us if we decide in the future to add real $-based macros to CSS. Again, we do understand why Web Authors prefer a compact and simple notation like $foo but we have decided it comes at a too expensive cost right now. We may reconsider this decision in the future (don't forget the spec is only a Working Draft at this time) but this will require solving all the issues detailed just above. Thanks.

Tuesday 19 June 2012

Media Queries and the 'view-mode' Media Feature are REC

Both Media Queries and the 'view-mode' Media Feature became officially a W3C Recommendation today. Yay !

Media Queries: http://www.w3.org/TR/2012/REC-css3-mediaqueries-20120619/

The 'view-mode' Meda Feature: http://www.w3.org/TR/2012/REC-view-mode-20120619/

Wednesday 6 June 2012

Transforms, Transitions and Animations

The CSS WG just resolved during its weekly conf call to allow browsers vendors to unprefix CSS 3 Transforms, Transitions and Animations immediately.

Wednesday 25 April 2012

The Open Web and CSS prefixes

Remember what I said a while ago here? I was not lying, here we are. :-(

Friday 3 February 2012

Wysiwyg is hard #5, CSS 3 Animations...

CSS 3 Animations are super powerful. I can't wait until they finally kill our JS-based animations. But they raise an issue that is well known by editor vendors: they're extremely difficult to manipulate in a wysiwyg environment, I already talked about it. As a matter of fact, none of the existing Animations editor on the market is able to edit a CSS 3 Animation wherever it comes from.

Here's the stylesheet I want us to look at today:

@keyframes bgchange {
  0%   { background-color: white; }
 100% { background-color: #b0b0b0; }

a { animation-name: bgchange; }

.dynamic { animation-duration: 1s }

What should a visual editor of Animations do with that ? It's totally impossible to infer from that stylesheet only that the dynamic class can apply in our document to anchors, so it's impossible to know the duration of the bgchange animation when it is applied.

An editor could present the bgchange keyframes rule, but only in a 0%-100% scale, not in a timeline since no duration is specified here. Even if you look for style rules specifying an animation-name, you won't be able to find an animation-duration...

In fact, we have this problem because we are mixing in CSS 3 Animations two notions: the animation itself and assigning an animation to an element. Authors of CSS 3 Animations chose to decorrelate the animation from time, and we have only percentages in the @keyframes rule. But that means such a rule cannot be presented as a timeline. They also chose to implement the assignment in a way the keyframes assignment and timing assignments can be independent; so they can't be presented as a timeline either...

Since Animations are a major feature of CSS 3 that will inevitably trigger more standalone and web-based apps to edit them, I think we have a rather serious design issue here. Some solutions are possible, they all have upsides and downsides:

  1. change the default value of animation-duration; it's currently 0 and it could become for instance 1s. In that case, presenting a timeline is always possible. Harm to existing web pages is low, most of the animations are set specifying name and duration in the same style rule and are usually triggered by a class or attribute.
  2. stop having individual properties for animation name, duration, delay and timing-function. One property only setting the four. That way, one the CSS rules in our example above must become .dynamic { animation: bgchange 1s; } and we don't have editability problems any more. That change will require roughly two thirds of existing web pages to update their code since they often set the individual properties.
  3. modify the @keyframes syntax to include mandatory default timeline metadata for that keyframes set. For instance something like:
    @keyframes bgchange 1s 3s ease-out {
     0%   { background-color: white; }
     100% { background-color: #b0b0b0; }

    Since the animation shorthand property still sets animation-duration to 0, and since as said earlier most of the animations are set specifying name and duration in the same style rule, the effect on existing web pages will probably be minimal. If the web author does not use the shorthand but individual properties, unspecified properties (except animation-name of course) get their default value from the @keyframes rule. We also need to extend CSSKeyframesRule to be able to reach these default timeline values through the Object Model. I even suggest extending CSSKeyframeRule to be able to get the time corresponding to the percentage of that frame for the default timeline metadata of the current keyframes set. I must say this solution has my preference.

This list is not exhaustive at all and I'm all ears if you have something else on your mind. But we do have an editability problem here and that's one I would really like to see resolved, for once in CSS, or we will have only standalone and web-based editors able to edit only a very restricted set of Animations, and not all of them.

Please try to post your comments into www-style and not here. I started a thread here about this article and the problem it raises.

Monday 28 November 2011

One pseudo-class, one document, two layouts

It's possible at super-minimal cost to have for the same document liquid AND fixed-width layout, thanks to ZE POWA of CSS...

In a fixed-width document named index.html, you usually have a rule setting the width or max-width of the main element. Something like

#main750 {
  max-width: 750px;

Right? Now think :target pseudo-class and tweak your style rule as followed:

#main750:target {
  max-width: 750px;

Do you understand the trick?

Yeah, your document now has liquid layout if called by URL index.html and fixed-width layout if called by index.html#main750 :-) TADA !

Wednesday 23 November 2011

Some thoughts about editing CSS 3 Animations

I started working on an editing tool for CSS 3 Animations inside BlueGriffon. And I discovered that editing Animations is hard. Just like the rest of CSS, eh :-) Animations are powerful but hard to edit in the general case.

Case 1

We have a html document with one @keyframes myAnim1 { ... } rule. When the user clicks on a given element, another element acquires through JavaScript an animation-name, an animation-duration and an animation-delay. In other terms, an editing environment opening that html document cannot determine from the document instance the animation myAnim1 can be attached to the element, when it should start and how long it will last.

Case 2

The document contains the @keyframes myAnim1 { ... } rule but myAnim1 is used through animation-name by two selectors targeting two different elements in the stylesheet. The corresponding animation-duration and animation-delay differ. Then the keyframes' set myAnim1 must be represented twice on a timeline, and the key here is clearly the selector.

Case 3

The Web developer is a JavaScript zealot and all animations are launched and chained through JavaScript instead of using a single class on a single element,  descendant combinators and animation-delay. Then it's impossible to present a  timeline of all animations showing when they will start and end, proposing a global vision of the animations' set of the document.


Because of the above, a single timeline for all animations living inside a document is impossible in the most general case. I mean, if you take an arbitrary Web document retrieved from an arbitrary Web site using Animations, it's very unlikely that you'll be able to edit these animations using an editor showing a single-timeline view.

Sencha Animator shows a single timeline and that's why it is unable to deal with an arbitrary Web page. Adobe Edge is a worse case since it deals with Animations only through a huge JavaScript library... Launch Edge, make an animation, export the document, look at the CSS : it's empty.

So my editor will have two views, one for the keyframes' sets, one for the selectors and the animation properties. It's a little more complicated (although I'm not really sure about that) but it will allow you to edit all your CSS 3 Animations. Unless you used Edge and its ugly JS-based design, of course ;-)

Animations Editor sketch
Click to enlarge

Wednesday 16 November 2011

CSS vendor prefixes, an answer to Henri Sivonen

Disclaimer: I'm one of the two co-chairmen of the CSS Working Group and the opinions below reflect exactly what I think of the CSS process not only as an individual contributor but also with my co-chair hat on.

The ineffable Henri Sivonen has contributed a long, a very long, a probably too long post about CSS Vendor Prefixes. In short, he thinks they are harmful and should be dropped. I tend to totally disagree and will explain why below. In bold, Henri's words. Indented and normal, my responses.

vendor prefixes are hurting the Web
No. Said like that without justification and as a first sentence in Henri's prose, no. They are not. Vendor prefixes allow vendors to implement experimental CSS features without harming the namespace of unprefixed properties.

They are hurting Web authors
Here, I agree. As they are now, vendor prefixes are hurting Web authors because a) the browser market does not evolve that fast, in particular on mobile devices b) some browser vendors never get rid of prefixed properties. As a result, Web authors have to maintain several prefixes properties per feature.

They are hurting competition in the Web browser space
I totally fail understand why, maybe the rest of Henri's article will explain why.

It would also make sense for browsers to implement other browsers’ prefixed features to the extent existing content uses prefixed features
This is non-sense. There are only two cases : first case, the prefixed property was proposed for standardization and then all browser vendors will probably implement it ; second case, it was not proposed, probably because it's too proprietary or badly spec'd, and no other browser vendor will implement it because it lacks a good definition or use case.

Why do we have vendor prefixes?
Henri says the discussion is Member-confidential. It is only because that discussion is super old, long before the CSS WG decided to go public. There is nothing secret here : we have vendor prefixes because vendors needed a way to start implementing new features w/o saying their implementation was the official final CSS property.

there is no clear rule for using vendor prefixes in the DOM
That's correct and that is hurting the Web. Mozilla does it right: when it implements a new API these days, everything is prefixed with moz. That way, if the final standardized API differs from the experimental implementation, it's easy to get rid of the moz-prefixed version, tell authors hey guys this was experimenal anyway, and finally switch to the stable standardized version.

Vendor Prefixes are “Hell” for Web Authors and Authoring Tool Vendors
That is 100% true, as I detailed above for Web authors. For Authoring tool vendors, it's a nightmare. But let me tell you one thing: the "HTML live standard" of the WHAT-WG is a nightmare of a MUCH greater magnitude than this one. In comparison with the fact what the whole world has now to call "HTML" can change overnight, CSS vendor prefixes are a sweet, predictable, simple candy.

Web authors have to say the same thing in a different way to each browser
Only because browser vendors are shipping "experimental features" in non-experimental versions! Experimental features should be available only in "technology previews" of the browsers, not in stable versions. That way, everyone could still test the experimental features according to the W3C rules BUT Web authors would not use prefixed versions in production. Since almost all browser vendors switched to a fast release process, I don't see the problem here. A feature would move from prefixed to unprefixed as soon as the spec reaches stability, ie CR status.

pure hell
I have the feeling Henri is using my opinion here to tell the world a "Live CSS Standard" would be better. I have the gut feeling he's advocating for a WHATWG way of doing in the CSS Working Group. I think this is totally wrong. I think this would make CSS collapse and trigger the hatred of CSS Authors because they will be totally unable to say what is CSS at a given point.

When the possibility of using engine-specific prefixes exists, engine-specific Web content follows.
This is just false. CSS stylesheets are full of CSS hacks because the different browsers don't evolve at the same speed, because they don't all offer the same feature set at the same time. Even if prefixes are removed, that will persist and therefore engine-specific Web content will persist.

Thus, a Web author who does not want to poison the standard namespace will only use the prefixed CSS keywords or DOM APIs
NO. Henri just doesn't understand Web authoring here. The only way to stop harming a stylesheet with different prefixes for the same property is to stop using prefixed properties. EXPERIMENTAL features are experimental, and Web authors are using them because browser vendors are shipping these features as if they could be used in production. They cannot. They're subject to change or even disappear at any time.

If a site uses CSS with the -webkit- prefix, users of Firefox, Opera or IE get a worse experience even if they implemented the same feature with their own prefix or without a prefix
It's only because browser vendors are dumb. And I do mean it. The rule should be this one: if the CSS parser encounters a prefixed property for another browser, honour that property as if it were prefixed for us UNLESS an unprefixed or prefixed for us valid declaration for that property was already set. That would drastically reduce the problems on the Web. Of course, if -webkit-foo and -moz-foo are not based on the same version of the spec - and that happens all the time - that will be helpless.

Back in the old days when Internet Explorer introduced a feature that they just made up, they did not make their mark on it by baking their name into the identifier
Totally false for CSS. Microsoft Word is full of totally proprietary -ms-* properties since the first version of Word based on XML and CSS, in the "old days".

Last week, insertAdjacentHTML finally shipped to the Firefox release channel.
Unprefixed, yes. But that's normal, we have here a de facto standard, IE and its online doc, where we usually have a de jure standard, a W3C specification. That IE feature is more than ten years old and the IE-specific Web is full of it. It is totally out of question to do something even lightly different from what IE does. So prefixes are not needed. We already have the standard!

The situation is harmful for Firefox for mobile, Opera Mobile and IE on Windows Phone.
That's possible and I don't care. What I see is that your proposal to get rid of prefixes will be even more harmful to non-browsing tool vendors, Web authors who will never know if a feature is experimental (and then subject to changes) or not, and finally Web users.

In a word: No.
No only because at the time a standard is published, the Web is already full of prefixed properties. And the Web is full of prefixed properties because browser vendors ship experimental features to all final users, allowing Web Authors to use these experimental features in production Web sites. Even telling them "go ahead, it's tagged experimental but it's shipped to everyone anyway".

Lea Verou's prefix free...
...is in my opinion dangerous. It tells Web authors that a prefixed version of a property equals another prefixed version of the same property. And that is just false. Lea's prefix-free tool is FAR from enough. Trust me on that please, I had to implement a few thousand lines to start working around the problem and I only have a partial solution... This is MUCH MORE complex than what Lea's tool lets Web Authors think it is.

In practice, vendor prefixes don’t prevent legacy from accumulating ahead of CR. It’s not useful to pretend that they do.
Again, only because of browser vendors themselves. They wanted CSS prefixes but don't use them according to their original wishes. Experimental is experimental, ie "should not be used in production". Since whatever you ship will ALWAYS be used and abused, shipping experimental features to the masses could only lead to legacy prefixes accumulating in the wild. This is browser vendors' fault.

If -webkit-CSS meets the client requirement within budget today, -webkit-CSS is used.
Exactly what I said above. So don't make -webkit-CSS available to the masses. Make it available in tech previews, beta channels, etc. But not stable versions.

browser vendors should stop adding more prefixed CSS features and DOM APIs
Basically, it says CSS should become a Live Standard. I totally disagree and will do all I can to avoid that.

For CSS, features like this include at least Transitions, Animations, 2D Transforms and 3D Transforms
That opinion would be hilarious if it was not tragic... These features are almost similarly implemented but there are still stuff discussed in the spec itself. The standardization is NOT done yet, and the features are complex enough a new painful hole could emerge in the coming weeks.

I also think that it would make sense to unprefix single-vendor features
Ah, that I could agree with IF there is some sort of formal environment here : a) the vendor must consider its implementation is frozen b) it was shipped for the first time more than a year ago, so this implementation is now a de facto standard because Web sites are using it.

In these cases (flexbox, gradients), I think it would make sense to stop changing the spec, to unprefix the features in browsers that are closest to the current drafts and then prioritize work to match the spec in other browsers
Clearly no. That's what the WHATWG does, only implementations matter and specs don't, as Hixie told me during TPAC. I don't want to see that happen in CSS, ever. Furthermore, it would trigger an absolute nightmare for Web Authors and Web Authoring Tool vendors.

I think when browser vendors implement a feature experimentally, the feature should stay in experimental builds (nightly builds, “labs” builds or similar) until it is close enough to a “final” design that it can be taken as a constraint for future changes to the feature.
AAAAAH FINALLY. Here we agree entirely. Just what I said above.

I think the system where a WG can change anything until Candidate Recommendation (...) is fundamentally broken. I think decisions whether a feature can be changed should be depend on deployment.
I totally disagree. It's broken because browser vendors break it shipping experimental features in non-experimental versions. Basing prefix removal strictly on deployment is the most harmful decision to Web Authors and Web Authoring Tools that you could take. Only stability matters, not deployment.

Update: now it's clearer. One of Henri's goal is to make CSS adopt the Living Standards way of doing things. My opinion is that it would kill CSS or at least be incredibly harmful to it. So I will fight that. And to reply to Rik in that IRC log, no, I don't always mention my co-chair role when I discuss CSS. I even mention "hat on" or "hat off" when I do.

Saturday 5 November 2011

CSS vendor prefixes, again...

We still have a major problem in CSS wrt CSS vendor prefixes... We have -moz-*, -webkit-*, -ms-*, -o-* and more all over the place and we all agree that what we have is suboptimal. During W3C Plenary Meeting this week, we discussed CSS Gradients. Introduced by Apple with a -webkit-* prefix, we now have at least 3 incompatible versions of gradients spreading in Web pages. Being myself an HTML+CSS editor implementor, I can tell you this is pure hell for me. But beyond editing issues, it's also a strong issue for Web authors because they have to maintain multiple versions of the same property in their stylesheets to be compatible with browsers that are not cutting-edge. Let's face it: we have a problem with Gradients (a really great feature by the way) because a browser vendor shipped it to the masses and there is no way to prevent web authors for massively adopt immediately such a great feature. It happened in the past for Gradients, it will happen again for other features.

On another hand, browser vendors need a way to implement experimental features and ship them, even if it's only for testing purposes. The CSS WG decided a while ago that if a given feature is stable enough across browsers, it should move faster along the REC track and the CSS WG should issue a call for implementations, tested with an official test suite.

But that's probably not enough. We still have one issue here: the "extraction" of a given feature from a given spec is not always easy, requires editing work and it's not instantaneous with respect to W3C Process. And if we keep the feature in its original spec, it means we call for implementations before the spec reaches a global interoperability, and that's not what the W3C Process wants. Thinking out loud, I wonder if a better solution isn't the following one:

  • new strictly-experimental prefixed properties and values can be shipped but they are disabled by default in content. It means that they will output a warning on the console at parse time and they will not be stored in the CSS OM, not honored in Layout. I understand this could slow down a little bit CSS parsers but nothing comes for free.
  • these experimental features can be enabled by the user using a special "Debug" menu.
  • a web page can programatically prompt the user to enable these features, through a new API probably on document. App-level (what we call chrome CSS in XUL) CSS does not need that, experimental features are still enabled by default in app-level CSS. I think enabling should be domain-wide, not global.
  • all experimental features are disabled again for all domains when the browser is updated.

Then browser vendors can still implement, ship, make the community test the implementation, allow Web authors use the features in experimental web sites.

Opinions? (again, I'm only thinking out loud here to start the discussion)

- page 1 of 6