scoped css/still missing in action

published on:
November 30, 2011
comments

What with rebuilding my blog and all, I ran into an old problem that I feel deserves some renewed attention. Two years ago I wrote a post about a missing css combinator (trying to overcome the strictness of the child combinator), sadly this combinator didn't find its way in any current (tentative) spec. This issue is more relevant than ever, so here is what I found out when asking how the css working group is trying to deal with this problem.

the problem

<section class="focus"> <header>...</header> <div class="main">...</div> <footer>...</footer> </section> section.focus > header section.focus > footer

I believe a quick recap of the issue I described in my previous article is in order, so here goes. The html setup above sets no extra classes on the header/footer elements, so the best way to style them is through the child combinator. This allows us to style only the header and footer of the focus block and not worry about nested content that might contain its own header and footer elements. Long live the child combinator!

The problem is that extra (sometimes unforeseen) wrappers in between section.focus and header/footer elements will completely destroy our carefully constructed css. Javascript might be inserting extra wrappers, a structural change (block level wrapper link or form) will lead to similar results. While the child combinator is extremely useful, in the end it might be too rigid for the needs of the web as we know it. Only in very controlled circumstances can it be used without worrying of breaking large chunk of css.

call to the w3

So I contacted the css working group once again to revisit this problem, in the hope to find a proper solution to counter this very shortcoming in the future. If you want you can read the entire thread you can, but I'll limit myself to the proposed solutions that were raised in the discussion.

:not syntax

section.focus header:not(section.focus article header)

Using the :not syntax we could single out the elements that should not inherit the css properties of the focus header. While this is somewhat helpful, the list of elements that should not inherit css can become quite long and is not always predicable. If you ask me, the :not syntax should be reserved for exceptions rather than a means to exclude 90% of the cases.

scoped css

@scope (scope-selector) { @stop (stop-selector) { (nested-selector) { ... } }

This is way cooler. A scoped css construction like this would allow you to define the edges of your component that would stop your css from spilling over to nested components. Rather than telling css what's outside your component, you are know telling it where your component ends and everything that's outside those edges should be ignored.

In theory this is quite awesome, at the same time I feel a powerful tool like this might be a weapon of self-destruction in the hands of someone not too familiar with css. I can already imagine an obese css file written in unnecessarily scoped rules. It's a tool that should be used with care by someone who fully realizes the consequences, then again, we're getting to a point where hacks and amateurs are struggling harder and harder to survive, so maybe it's not a bad thing to embrace some trickier tools to make our job a bit easier.

conclusion

I love the idea of scoped css, though it's not really clear to me right now if you can define multiple boundaries for one single component. It's not even certain that this is ever going to make it into the spec or even a proposition, so it's probably best not to get too excited yet.

That said, with ie6 slowly disappearing it's time we start to tackle the problems of the next-gen css (it's sad to call child combinators that, but it's still true I'm afraid). Hopefully the near future will give us something that allows us to finally style a component within the limitations of its own boundaries.

Comments

Niels Matthijs

comment number
date
November 30, 2011 12:44

While definitely closely related to each other, I always assumed that style@scoped way meant for inline css rather (so not for regular site styling, but syndicated or other external content). I could be wrong though :)

Mathias Bynens

comment number
date
November 30, 2011 13:00

Of course, but what you’re asking for is very similar to it. In fact, what you want is a CSS version of &lt;style scoped>. :)

George Katsanos

comment number
date
November 30, 2011 13:03

I believe the problem lies in the way CSS.. is. As many have said, http://www.gplus.gr/blog/index.php/2011/09/semantic-markup-css-and-crockford/ CSS is not modular, so you can't be sure 2 elements behave the exact same way. I can see the scope idea, but as you said already, CSS is considered to be an entry-level language (wrongly IMO), any junior/one-man-for-all-jobs "webmaster" will just create a mess or avoid using it at all..

Tim W.

comment number
date
December 14, 2011 08:43

Well, since jQuery offers an interesting set of DOM traversing selectors AND more and more CSS developers are becoming familiar with its syntax, why wouldn't the CSS working group take a page out of their book and keep CSS selectors in sync? I read somewhere in the thread that jQuery's .closest() selector does the trick.

The wonderful thing about both jQuery and CSS is its straightforward syntax, with most of the intricacies being hidden under the hood. They schould work together. How often do you use all that selector goodness in jQuery just to add some classname so CSS can be applied?

* required fields

Leave your data
Leave a comment