Wednesday, August 15, 2007

CSS and XPath selectors

Many people have noticed the similarities between CSS selectors and XPath - and it's fair to say that XPath is far more powerful.

In fact, XPath can do pretty much anything that CSS can, plus much more.

select the parents of all paragraphs:
select alternate list items:
//ul/li[position() mod 2 = 0]
select table cells with a value less than 10
//tr[number(td) < 10]/td

Yet another CSS wish - XPath stylesheet selectors

No existing browsers have XPath enabled inside stylesheets. But wouldn't it be great if they did?

All it takes is a new CSS selector - XPath(string), where string is an XPath expression.

For example, selecting paragraphs containing the word 'Chris':
XPath("//p[contains(., 'Chris')]") {border: 1px solid black}

Of course, XPath doesn't itself handle pseudo-elements or pseudo-classes like :hover - but we can mix and match the XPath function with other CSS (e.g. colouring any hovered paragraphs containing two hyperlinks):
XPath("//p[count(.//a) = 2]") :hover {background-color:red}
And it can work with other selectors too, e.g. finding <ul>s directly underneath any <p> element, and shading them alternate colours:
p XPath("ul/li[position() mod 2 = 0]") {background-color: white}
p XPath("ul/li[position() mod 2 = 1]") {background-color: silver}

Following the usual CSS rules, if the XPath function contained mis-formed XPath, the style could be ignored. Also, it would be ignored if it returned anything other than element nodes (i.e. no attribute nodes or strings). And the default starting node of the XPath query is the document element, unless clarified by preceding CSS selectors.

Why not implement it?

As you can see, just by adding a single new selector, the CSS language is extended in so many ways.

XPath has already been agreed as a W3C recommendation, and has already been implemented in the major browsers.

I therefore see no good reason, other than inertia, why such a powerful new feature can't be added as soon as possible!

1 comment:

dand said...

one disadvatage to comparisons in the selectors is speed. i would expect the matching complexity to increase exponentially.

you might consider using javascript to process the above sample as written.

it wouldn't work in browsers without js enabled, but the invalid rule should be silently ignored.

javascript could grab the text of the style tag, parse out the xpath, process it, and add a new stylesheet via the dom with the computed results...