Extending the list of CSS pseudos
By glazou on Tuesday 22 February 2005, 14:48 - CSS and style - Permalink
I know what will be your first reaction. Your first reaction will be one of the following ones (the two first ones if you are one of the inventors of CSS, and the fourth one if you are a swedish mozillian)
- this is ugliest thing in Earth's History and CSS should not rely on JS
- CSS should not be turned into a programming language
- think of the grammar, the parser would need to know the extensions before parsing a sheet
- possible deadlock if a rule uses such a user-defined pseudo and applies a behavior that makes that pseudo false
- why do you need to extend CSS pseudos' list anyway?
We have an XML- and JavaScript-based mechanism called XBL to extend element behaviors. We have a JavaScript- or c++-based mechanism called XTF to extend the list of "natively" supported XML elements. But we have nothing to extend easily CSS itself...
I think we could have a simple à-la-XBL mechanism to extend the list of pseudos and pseudo-notations in CSS. The definition of a pseudo could be JS-based and embedded in a specific XML dialect, just like XBL. That XML would define a method taking one single argument, the element we try to match the pseudo against, and it would reply a boolean. In the case of pseudo-notation (e.g. :foo(token)), extra arguments would be needed. Some typing information for the arguments would also be needed to allow grammar checking. Now back to the concerns above:
I won't discuss the first one, we won't change the Web now. The second one is IMHO irrelevant, CSS itself remains untouched. The third one is probably strictly implementation-dependant. The fourth one is a real problem but probably a marginal one; after all, we can already have a behavior applied depending on the existence of an attribute and removing that attribute... The fourth one is the argument that people who never go beyond their limits use. I can think of dozens of improvements to the list of CSS pseudos that **I** could use but that some other people could dislike. So an extensions mechanism is the best answer.
Before posting a comment, think three, four, ten times please. It would be so cool to be able to write something like
<css-extension>
<pseudo-class name="has-child">
<parameter name="elt"/>
<parameter name="childName" type="element_name"/>
<body>
<![CDATA
var childList = elt.childNodes;
if (!childList || !childList.length)
return false;
var l = childList.length;
for (var i = 0; i < l; i++)
if (childList.item(i).nodeName == childName)
return true;
return false;
]]>
</body>
</pseudo-class>
</css-extension>
And just apply it before your stylesheet with a LINK element or declare it in your stylesheet using an @import-extension url(..); rule.

Comments
I really like the idea, but at what point would the binding be called? Would it be after all of the element's children have been parsed/rendered or before any of them have been parsed? I know that IE has a bizarre dependency engine within its Javascript parser, but I don't know if that would be the right way.
At what point does the pseudo-class need to be recalculated - or is it up to the binding to set up the proper events and reapply (or remove) its class?
I suppose you could call the binding before any children have been parsed (when the element would be the last item in the DOM) and have it subscribe to DOM events whenever children are added/removed. This way, it would be up to the element to add/remove its application.
Comment ne pas penser à la pseudo-classe qui pourrait etre bien utile last-child qui n'existe pas alors que first-child lui existe ...
After further thought, I suppose that you could have the binding return null for an "indeterminant" state. Any element with a binding in an indeterminate state would effectively "hold up" the display of the document - all elements forward in the document would not be displayed until the binding was resolved.
This would be to avoid placing the "has children" style on an element as it was being retrieved from the server and then removed it once the first child has been retrieved, removing the chance of a styled or unstyled flash of content.
Wouldn't your pseudo-class have the same effect as www.w3.org/TR/css3-select...
Anno1602: not at all... div:has-child(p) would select the div while div > p would select the p...
Anno: no. With Daniel's idea you could easly prepare a pseudo like
p:second-link {}
tbody:every-second-row {}
etc. So you could extend CSS whith pseudo's that W3C did not parepare
Making CSS extensible... Isn't it time to rewrite CSS in XML ?
table :has-child(col)
Could this be the first step to solving the enigma that is bug 957?
> Making CSS extensible... Isn't it time to rewrite CSS in XML ?
What would that solve? XML is just a data format.
Having said that, it seems to me that one could get much of the benefit of this proposal for (I expect) much less effort simply by introducing a mechanism for allowing XPath in selectors. Something like xpath("{xpath-expression}") {}.
All I'll say is that your proposal here looks a lot like a specialized DOM node filter. (This isn't necessarily a good thing or a bad thing. It just looks similar, that's all.)
A style is just one kind of data. Computing is just setting up data structures, fullfilling them with data, using algorithmic methods... Data, data structures, algorithms. You see anything else in computing ? I don't.
XML is already and by design extensible, easy to extend, extended every day to answer users needs, that's what I tried to point out. With styles defined in XML files, extending a list of styles would be no problem. Parsing, manipulating XML files is so easy today... Manipulating CSS is not something that programs do so often. And why load two libraries when you can do things with only one in RAM ?
More seriously, why make CSS, a presentation language, A SPECIALIZED DATA LANGUAGE in fact (a style is definitely a data), extensible, as there already is one extensible language in the area, that could with much more ease integrate the "styles" type of data ?
I do not say it's the thing to do... I just thought Daniel's post was the kind of reading that makes me think about that kind of "radical" solution. Especially when the same Daniel writes about the "bad idea" that are CSS levels, and the advantages that CSS versions would bring. When you can think about doing something not compatible anymore, you can think about doing something simply... different, no ? And possibly with tools proven efficient and already widely known. XML is that. Rather than developing two different languages in parallel, I think there is a way here.
... Hard to be clear in english, I hope you understood me. If not please excuse me...
What's the use case? I don't mean this sarcastically. I'd quite like to know what made you think of this...
It seems that you could essentially do it already using XBL to define an attribute and then using an attribute selector to represent the pseudo-class:
[myProp="true"]
The problem comes with the dynamic nature of pseudo-classes vs attribute selectors.
Some of the CSS3 pseudo-classes (:checked, :disabled etc) could easily be described as "dynamic attribute selectors".
*:checked ==> *[checked=true]
For all known browsers, attribute selectors are not dynamic. If this were "fixed" then many of the CSS3 pseudo classes would become redundant.
Maybe this is better than tampering with the fundamentals of CSS? I admit that the programmer in me would love to see a way to insert JavaScript into CSS. But I think that they should remain separate (with the exception of behavioral extensions).
Cheers Daniel!
>Making CSS extensible... Isn't it time to rewrite CSS in XML ?
Interesting. Maybe you could have something like:
<css-rule selector="h1 > p">
<declaration property="font-size" value="12px"/>
<declaration property="color" value="blue"/>
</css-rule>
but then you'd still need to use the regular CSS format to use inline styles (to say nothing of backwards compatibility).
Earlier I got excited by the idea of having an XML representation of Javascript. This ranked high in coolness factor because it would allow you to write programs that manipulate other programs (through the DOM) or use XSLT on code. I did a web search and found out that someone had already come up with an XML format for C++, www.scl.csd.uwo.ca/Projec... including a modified gcc to rewrite existing C++ code into this new XML format as well as to compile the format.
So you could conceivabely write all portions of a webpage (HTML, CSS, and JS) in XML. Of course, writing CSS and Javascript as they are now is much easier than writing them in any (bloated) XML format, so this would only be something automated programs would use. It would take a lot of work to implement and I'm skeptical if there would be any practical use for it. You can already manipulate CSS with the powerful CSS DOM. Perhaps there could be a "JS DOM" to manipulate JS code easily...
But anyway, I really like Glazman's idea, although I suppose you could make due with a BODY onLoad javascript event to change the styles of the elements you want.