<Glazblog/>

CSS and style

Cascading Style Sheets and other exotic stylistic animals

Entries feed - Comments feed

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.

Conclusion

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)

Friday 30 September 2011

Selectors 3 and CSS Namespaces Module are RECs

At the end of 1998, a while after the release of CSS 2, I took an action item in the CSS Working Group to become the author/editor of a new beast in our Group, a module... CSS 2 was already a big big change from CSS 1. And when I say 'big', it means the spec switched from the 15 printed pages of CSS 1 to the hundreds of CSS2. So we decided to 'modularize' CSS 3. Since I already worked a lot on Selectors and even implemented them before, this was a natural choice for me.

At the beginning of january 1999, my first draft was ready. It's unfortunately not public and the original document was lost when I left my employer a year later (Electricité de France, fwiw). The second draft though is still available, although in a web space restricted to CSS WG Members, sorry for that... The first public draft, dated 03-aug-1999 is available here. You can see that in that document, the :subject pseudo-class, corresponding to the $ descriptor present in the current Selectors 4 draft, was present... Alas, it was later removed because of browser vendors expressing implementation concerns. That pseudo, a top request from the Web Authors' community, originally came from something I specified and implemented myself in my transformation language based on the CSS syntax/grammar: STTS3.

Despite of what I could call a poor support from implementors at that time, I also decided to add major new stuff to Selectors:

  • the :nth-child() and friends pseudos, captured from an early draft of XSL/XPath I found impressive. I really wanted them to be able to style table rows, columns and cells. For the record, the an+b syntax of the argument was proposed by Tantek Çelik's father.
  • the :target pseudo, proposed by Håkon Lie. Håkon did not suspect the power of that pseudo at that time, until I found a super-interesting use case for that pseudo... See the demo (in a browser implementing :target, of course...).
  • the indirect adjacent combinator ~, that was really missing.

Then namespaces and the negation pseudo :not() arrived, and the spec changed only a little bit between 2000 and now, waiting for browser implementations, a completed Test Suite and interoperability.

Today, after more than 12 years, I am happy. Really happy and a bit proud too I must say. Older, but happy :-) My baby just became a W3C Recommendation, after the hard work of many people who caught the flag and became editors of the document and/or the Test Suite... Yay!

Similarly, the original CSS Namespaces proposal, authored by my co-chair Peter Linss during the Netscape era (gosh, time flies...) became a REC yesterday after too many years of wait. Yay again !

All in all, the CSS Working Group released 5 new W3C Recommendations between the beginning of june 2011 and now ! Wooohooo !

So where are we now? Selectors 4 start emerging, and I would like to issue here a clear and loud warning with my CSS WG Co-chair hat on: this is an early stage draft and the presence of a feature in that document does not imply IN ANY WAY that the final specification will contain it and that browser vendors will offer support for it. In particular, I already noticed the major response of the community to the presence of the subject selector and the matches-any functional pseudo-class. Guys, please cool down... These two features still represent a real implementation challenge for browsers and I just cannot tell if they will remain in the spec or disappear from it. Please note, this is not the first time - as I wrote above - such features are included into a Selectors draft... Been there, done that.

Don't misunderstand me ! I am not saying these features will never ever reach a browser near you ! I am only saying standardization is a complex process also based on implementability of the features we design AND browser vendors' strategies. Be optimistic, but also be realistic. Thanks.

Tuesday 7 June 2011

CSS 2.1, CSS 3 Color and MathML for CSS Profile are RECs !!!

YAY !!!!

Tuesday 24 May 2011

CSS OM, issue #2

In the CSS Object Model, interfaces CSSStyleDeclaration, CSSRule and CSSValue have access to the attribute cssText. So basically, you can serialize a stylesheet using that. All of a stylesheet? Unfortunately not...

  1. first, nothing is said in the DOM about the character set used to serialize your stylesheet in cssText. Even if your stylesheet uses a @charset rule, it's likely your serialization through cssText will be utf-8 utf-16...
  2. then @namespace rules are not available through the DOM at this time. I should add there is no CSS OM extension for them in the CSS 3 Namespaces module because there was no consensus about that and it was left for the forthcoming CSS OM spec.
  3. because of the previous item, it's just impossible at this time to serialize a stylesheet using namespace prefixes unless your rendering engine has proprietary extensions to deal with @namespace rules. There are two options here: a new type for CSSRule and then a simple loop over all rules in the stylesheet is enough to serialize it (modulo the charset issue mentioned above), or a table of prefixes/URIs attached to the stylesheet itself and then you need two loops; one for @charset and @import rules, the serialization of @namespace rules and finally the second part of the loop over remaining stylesheet rules.
  4. cssText is not available on CSSStyleSheet. On that interface, cssText could do all we need above: deal with namespaces, convert to the correct charset, and whatever we need in the future.

Thursday 19 May 2011

CSS OM, issue #1

I am starting with this blog entry a list of CSS Object Model issues I am hitting working on my editor, BlueGriffon. Here's the first issue below, more to come later:

Interface CSSStyleSheet does not deal with rules but only with rule indexes. Just like CSSMediaRule. That has an immediate side effect for content editors willing to edit stylesheets: moving a single rule in the list of rules attached to a parent stylesheet or parent media rule will not preserve the reference to your rule! Given a valid index in a stylesheet sheet, the following code moving the rule down into the list of rules will return false:

var rule = sheet.cssRules.item(index);
var newIndex = sheet.insertRule(rule.cssText, index + 1);
var newRule = sheet.cssRules.item(newIndex);
sheet.deleteRule(index);
alert(rule == newRule);

This is clearly suboptimal. CSSStyleSheet and CSSMediaRule should be able to deal directly with rules. I suggest adding the following to Anne van Kesteren's improvements to the CSS OM:

readonly CSSRule insertCSSRule(CSSRule rule, unsigned long index);
void deleteCSSRule(CSSRule rule);

That way, the code above could become:

var rule = sheet.cssRules.item(index);
sheet.insertCSSRule(rule, index + 1);

And that's all. insertCSSRule() would detect rule is already present in the list of rules of sheet and simply move the rule to its new position.

Wednesday 18 May 2011

Wysiwig is hard #4, editing StyleSheets...

Editing stylesheets in a wysiwyg editor can be hard. For multiple reasons:

  1. stylesheets are of three different kinds: embedded into the document through a <style> element, linked through a <link> element, or imported from another stylesheet (and nesting is possible) through an @import rule. In html5, the possibility to have embedded styles anywhere in the document adds another layer of complexity, in particular in the case of presence of the scoped attribute... I must admit BlueGriffon is not ready for that yet, I have not resolved all the technical issues related to scoping. In particular, the specificity of scoped styles is unchanged and I am not sure this is coherent with the spirit of the CSS Cascade. This may have deep implications on the wysiwyg editing side but an ID selector's specificity should probably be added to all scoped styles.

    Listing all stylesheets applied to a given document is simple using one single CSS OM call. Determining if a stylesheet is embedded, linked or imported is done through the parentStyleSheet and ownerNode attributes on CSSRule and StyleSheet interfaces.

    Serialization of a stylesheet is painful. I had to write thousands (yes, really) of lines of JS to handle that because unknown CSS rules are not preserved by the browsers' style engines. Even if they were, an editor just cannot consider a vendor-prefixed property has to be output unchanged. A style change by the user could affect vendor-prefixed styles stored as unknown rules in the CSS OM...

  2. adding a given style to a given element is hard; not only you must find all the style rules that apply to the element for the property you want to edit, but you also need the specificities of those rules. When you have the list of couples (rule, specificity of the rule), you must find the rule of highest specificity. If that rule is editable, i.e. if the stylesheet can be modified by the application, then you must create a style rule or a style attribute of a high enough specificity and/or importance overriding the current style. If the stylesheet is not editable (file not writable, remote resource), then you may have to create a new embedded or linked stylesheet (or use a style attribute) to apply the style you want. I don't even want to think about the scoped styles case for the time being, it's a nightmare.

  3. html5 defines a new presentational attribute on all elements: the hidden attribute... It is not entirely clear to me if a true value of that boolean attribute should map to the CSS display: none; style or use another mechanism to hide the element. In the case of the former choice, this will add another layer of complexity to the editing algo for the display property. Furthermore, in the case what's the position of the hidden attribute in the CSS cascade? I think the html5 author's spirit make it override all other styles. But that's not how the Cascade works, giving a very low specificity to presentational attributes. Should the hidden and the style attributes have the same specificities? Should hidden exist at all? I don't think it should. It's presentational and we have the display property anyway. The only reason why it should exist could be an accessibility reason, voice browsers often using the DOM and not the CSS OM. By the way, the spec says "When specified on an element, it indicates that the element is not yet, or is no longer, relevant". Does it imply that styles contained in a <style hidden> should not apply any more? In other terms, does it disable the stylesheet? This hidden attribute is a can of worms, underspecified, and it will raise tons of technical issues in the near future.

  4. editing an embedded stylesheet is a pain. I'm sure you thought this should be the easiest case. No external file or remote resource, everything is inside text nodes. Simple, eh? It's not. It's not if you want the dialog editing such a stylesheet to be non-modal... Let me explain: if the dialog is not modal, then all changes to the styles are immediately applied. Let's suppose my embedded stylesheet contains only p { color: red; } and that I want to change that color to blue. I have two choices depending on the frameworks I am using:
    1. first case, I have access to an abstraction layer allowing me to tweak directly the source of the stylesheet; then I can change the red into a blue, and replace the textual contents of the style element by the new stylesheet
    2. I have only access to the CSS OM; then I can change the property value in the CSS OM, serialize the stylesheet and then replace the textual contents of the style element
  5. But in both cases above, I have a serious problem: the stylesheet I was editing does not exist any more! The style rule I was editing does not exist any more! They were replaced by a new stylesheet and a new style rule after parsing of the new textual contents... So if I kept a reference to the stylesheet and style rule I edited, they suddenly get a null ownerNode, my whole UI still shows style objects that are now only references to objects unrelated any more to the document. That implies that every style change, I repeat every style change, in an embedded stylesheet from a non-modal UI should totally reflow the UI or at least, reassociate all UI to new style objects that did not exist before... Urgh, to say the least.

Editing styles in a wysiwyg editor is not, as I heard it during a chat a few months ago, "only a matter of a few calls to the CSS OM". It's painful, expensive both in terms of performance and footprint, sometimes tricky in terms of UX and requires stuff that the CSS OM does not implement . It can be really hard.

Wednesday 30 March 2011

CSS 2.1 !!!

plinss: I propose advancing 2.1 to PR
plinss: Any objections?
RESOLVED: Advance CSS2.1 to PR. 

Tuesday 29 March 2011

border-radius rant...

Sorry to be less technical than in general but something painful just happened to me while working on the CSS editor of BlueGriffon and I wanted to share that with the CSS community...

BlueGriffon is based on the source of Firefox 4. The border-radius property is then implemented unprefixed in the rendering engine. Even if BlueGriffon outputs styles for other rendering engines (using Peter Beverloo's excellent list and my JSCSSP parser/serializer), I considered that one version (the last public one) of each rendering engine is enough.

And I just got a mail from a user complaining that -moz-border-radius is missing...

From a user's perspective (hear web author's perspective), this is a perfectly fine request. From my software implementor's point of view, it's a nightmare.

If CSS vendor prefixes are useful for standardization and implementation of experimental features, they're harmful to the users' community and painful to software management. Our current situation wrt vendor prefixes is still suboptimal, to say the least.

I am not going to support in BlueGriffon prefixed versions of properties that are now unprefixed in the last public version of browsers. Example: I don't plan to support the WebKit gradients forever...

Friday 18 March 2011

CSS Avancées

CSS AvancéesRaphaël Goetter vient de publier chez Eyrolles son nouveau livre "CSS Avancées, vers HTML 5 et CSS 3" que je ne peux que chaleureusement vous recommander. Pour vous mettre un peu l'eau à la bouche, voici le texte de la préface rédigée par votre serviteur pour le livre:

Au début étaient la pierre, le bois, l'argile, le métal, le papyrus et finalement le papier. Des supports pour lesquels fonds et forme sont inextricablement mêlés. Séparer la lettrine de son enluminure ? Imaginer le Talmud sans son formatage si spécial permettant les commentaires ? Impossible ! Pire, les éléments de forme étaient fortement dépendants du support : la typographie ronde était difficile sur pierre et impossible dans l’écorce de bois, les barres supérieures de certaines graphies étaient là pour aider l’alignement.

La révolution technologique a non seulement séparé fonds et forme dès la naissance du télégramme, mais elle a également séparé fonds et format, les lettres et chiffres n’étant plus des lettres et chiffres mais des signaux morse transitant dans un fil métallique. Le Web, cette nouvelle révolution dont seuls nos descendants mesureront à sa juste valeur la portée, va encore plus loin et officialise enfin ce vieux leitmotiv des fanatiques de la documentation structurée : contenu et présentation sont deux notions quasi orthogonales. Un contenu donné peut être présenté de plusieurs manières différentes, une présentation peut être commune à plusieurs contenus sans rapport entre eux.

Lorsque le Web nait au CERN entre 1989 et 1991 sous l’impulsion de Tim Berners-Lee, rien de tout cela n’existe encore. Chaque élément de la lingua franca du Web, le langage HTML, véhicule intrinsèquement sa propre présentation et styler un contenu n’est pas encore une idée en vogue. On est encore bien loin de ce qu’offre la PAO…

C’est là qu’interviennent Håkon Lie, un norvégien qui travailla au CERN avec Tim Berners-Lee et fût l’un des premiers employés du World Wide Web Consortium, et Bert Bos, un néerlandais étudiant à l’Université de Groningen. Extrayant la substantifique moelle des technologies de style documentaire existantes et comprenant que le style peut se décliner en styles voulus par l’auteur du document, styles par défaut de l’outil de visualisation et enfin styles imposés par le lecteur, ils ont élaboré de 1993 à 1995 le concept de Feuilles de Styles en Cascade (CSS).

Les débuts furent difficiles. Les éditeurs de navigateurs Web se livraient une guerre acharnée et une solution standard, interopérable et surtout exigeant des changements fondamentaux dans leur code n’était pas nécessairement bienvenue. Il fallut donc attendre un très grand virage sur l’aile, celui de Microsoft vers l’Internet et le Web, pour voir enfin les CSS implémentées de façon sérieuse et extensive dans un navigateur Web. A titre de rappel, le premier navigateur à proposer le support intégral des CSS 1 fut Microsoft Internet Explorer pour Macintosh… Netscape finit par abandonner son idée de styles fondés sur du code JavaScript (JSSS) et bascula vers les CSS. L’heure du succès était venue et la seconde mouture du standard, les CSS 2, s’aventura dans des champs encore inexplorés sur le Web : les polices de caractères téléchargeables, l’impression, le positionnement fin, et encore beaucoup d’autres nouveautés.

Mais les hommes n’étant finalement que des hommes, CSS 2 alla trop loin pour eux et l’implémentation des CSS 2 dans les navigateurs ne fut jamais à la hauteur des espoirs initiés par la spécification elle-même. Certaines fonctionnalités étaient sous-spécifiées, certaines autres posaient problème, certaines étaient même tout simplement inimplémentables en l’état de l’art ou de la spécification…

Le World Wide Web Consortium (W3C) s’attacha donc à la révision des CSS 2 en même temps qu’il planchait sur la future mouture, CSS 3. Cela prit un certain temps, voire un temps certain. Malgré une certaine exaspération toute légitime du côté des éditeurs Web, cela eut un effet très positif en laissant aux éditeurs de navigateurs le temps de profiter de nombreuses améliorations hardware et software. Un navigateur Web de 2010 n’a plus rien à voir avec un navigateur Web de 2000, même si l’usager ne s’en rend pas toujours compte.

Aujourd’hui, CSS 2.1 est enfin en phase finale de standardisation. Les CSS 3 ne sont pas un rêve éthéré mais une réalité déjà utilisable dans tous les navigateurs du marché. Tous ? Oui, tous, y compris Internet Explorer 9.

Non seulement plus personne ne conteste le modèle et l’utilité des CSS, mais plus personne ne conteste plus non plus leur légitimité en tant que langage unique de Feuilles de Styles sur le Web. Les fonctions de formatage simples des CSS 1 ont été grandement étoffées, et les dégradés de couleurs, les transformations géométriques, le colonage, les polices de caractères téléchargeables, ou encore le texte vertical et l’internationalisation promettent de servir des sites Web encore plus modernes, plus réactifs, plus conformes aux standards, plus aisés à réaliser ou maintenir et tout simplement plus beaux à encore plus d’internautes dans le monde, sur ordinateur ou sur mobile.

Que vous soyez l’éditeur d’un grand site de presse ou celui d’un petit blog, la conception de votre site passe immanquablement par les CSS. Et continuera encore plus à l’avenir à passer par les CSS… Car l’histoire ne s’arrête pas là : le Groupe de Travail standardisant les CSS au W3C continue à avancer, à répondre de mieux en mieux aux demandes des Web Designers ou même des typographes. La convergence entre le Web et les autres métiers du design documentaire est en marche : grilles de design, modèle flexible de présentation, etc. Vous allez adorer ça autant que nous aimons le standardiser et l’implémenter.

Le livre de Raphaël Goetter est donc pour tout auteur de site ou rédacteur d’une newsletter à envoyer par mail un must qui lui permettra non seulement de tirer parti des nouvelles technologies du Web (CSS 2.1 et 3, HTML 5) mais également d’éviter les chausse-trapes.

Entre le hêtre (*bōkz en proto-germanique) et l’e-book, le mot n’a que peu varié. Et la maîtrise du second requiert toujours la lecture du premier. Bonne lecture, donc !

Daniel Glazman
W3C CSS Working Group, Co-chairman

Tuesday 8 March 2011

Beyond CSS 3 Selectors

I want a change in Selectors, my baby, for post-CSS 3. Section 6.6.5.1 of the current provisional REC says:

The :root pseudo-class represents an element that is the root of the document. In HTML 4, this is always the HTML element.

This is clearly not enough and I have a use case:

  • imagine you have two nested tables. You want to count the number of cells in the tbodies of the outermost table. That outermost table has no ID, no class, nothing to differenciate it from another table in the document. Let's call that outermost table mytable. Then mytable.querySelectorAll("tbody > tr > th, tbody > tr > td").length is not what we are looking for to count the cells because it will count ALL cells, including the cells of the innermost table... :root does not help here because it does not represent the root of the current scope. The :not() functional pseudo does not help either. The count cannot be performed using querySelector or querySelectorAll even if it could be the easiest, the simplest way. (This is not an imaginary use case, I hit that issue in BlueGriffon...)
  • imagine you have a scoped stylesheet applying to a subtree with the root of the subtree being a totally arbitrary element. It has no ID, no class you can use, nothing. It's then NOT selectable in the scoped stylesheet at all, you cannot apply styles to that element through the scoped stylesheet...

So I want the following change for the next step of Selectors:

The :root pseudo-class represents an element that is the element root of the current scope. In the case of CSS, the current scope is determined by the following rules:

  • if :root is used inside the parameter of a call to a.querySelector or a.querySelectorAll where a is a Document, then the current scope is the whole document
  • if :root is used inside the parameter of a call to a.querySelector or a.querySelectorAll where a is an Element, then the current scope is the subtree of the document a is the root of
  • if :root is used inside a non-scoped stylesheet, the current scope is the whole document
  • if :root is used inside a scoped stylesheet, the current scope is the scope of the stylesheet

That way, my count above is mytable.querySelectorAll(":root > tbody > tr > th, :root > tbody > tr > td").length and it is possible to style the root of a scope using the trivial selector :root. In the current CSS 3 case and non-scoped stylesheets, :root still means the root of the document. In the case of calls to Element.querySelector or Element.querySelectorAll, these calls reply an empty list anyway if the argument contains a :root pseudo and if the element is not the root of the document. In other terms, it's not something web authors use because it's totally useless at this time.

Sunday 26 December 2010

confoo.ca

J'aurai le plaisir et l'honneur de causer dans le poste à la conférence confoo.ca à Montréal entre le 9 et le 11 mars prochain ! J'y parlerai évidemment de CSS... J'ai hâte d'y être et de découvrir enfin Montréal !

- page 1 of 5