W3C home > Mailing lists > Public > www-style@w3.org > October 2008

Selector Sugar

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Thu, 9 Oct 2008 10:53:23 -0500
Message-ID: <dd0fbad0810090853r3b774e53vf0c88b6ad255b1b0@mail.gmail.com>
To: "W3C Style List" <www-style@w3.org>
I want to talk about two issues of syntactic sugar that I believe would be
very useful to us authors.  Neither actually change anything in the way CSS
works or produce new burden on implementors - both are merely sugary
conventions that would allow us authors to shorten some thing we currently
write out manually.  I know I've seen both of these suggested before in
various syntaxes; I just want to bring them together in what I think is an
appropriate syntax for each, so as to provoke new discussion in a thread
specially dedicated to them.

(1) Scoped selectors within a stylesheet.

Good, semantic authoring often entails a relative paucity of named hooks
into the document (in the form of ids and classes), with most of the actual
CSS targetting being done through relatively complex selectors descending
from some named hook.  Frex, a navigation menu may *only* id its enclosing
div, and target all of its styling purely by structurally descending from
that #id.  The issue with this is that you have large swathes of selectors
that share a common prefix, which must be repeated on every single rule.
This can be simplified by creating a block in which every rule is assumed to
be scoped to an area.  My first thought is an @ rule, something like the
following:

@scoped( #nav-menu ) {
h1 {
//This is equivalent to the selector "#nav-menu h1",
//and so won't target <h1>s across the rest of the page.
...
}
ul {
...
}
more rules...
} //end of scope

I would find benefit from this immediately, as all of the sites I operate on
utilize the same basic mechanisms.  They consist of a template which is
styled by a dedicated sheet, and then has content piped in from a database
which also pulls in the page-specific styling.  The page-specific styling
should *never* affect the outside template, and current I accomplish that by
iding the content container and just prefixing *every* rule in *every* page
with that id.  I've purposely made the id extremely short (it's just "bc"
for "body content") so it's not overly burdensome to type, but that's still
a lot of meaningless typing that could easily be taken out with the addition
of a single scoping line.

Even past the convenience factor, there's a safety factor.  I hand-craft the
styles across my company's site, because nobody else in the company really
has appropriate skill to do so, but even I sometimes forget to use the #bc
prefix on a rule.  The damage is usually immediatley obvious, as I suddenly
give every header some enormous background or something, but it's also
unnecessary.  Forcing other people who are relative newbs at styling to
remember to arbitrarily prefix all their rules with #bc as well is just
frustration waiting to happen.  I could, of course, build a CSS parser that
alters the rules myself, but why reinvent the wheel every time when it can
be simply fixed in the language itself?

Ignoring any possible optimizations, this is a simple matter of the parser
doing a simple textual concatenation before handing the selectors to the
matcher.  This construct should also be nestable, for obvious reasons.


(2) Multi-matching selector

This was suggested just recently and also came up in the jQuery thread a few
moments ago, and I would also benefit greatly from this.  The idea is that,
rather commonly, you have to apply the same style across several elements
with different classes or whatnot.  This isn't burdensome when you're
writing a single group of selectors, but when you have a large chunk of
selectors that all have to be generalized you quickly run into a nightmare
of typing.  For example, in something I'm typing *right now*, I have a lot
of selectors which look like this:
#top-courses div.chapters h3, #additional-courses div.chapters h3 { ... }

#top-courses and #additional-courses are two (of several) sections which all
share a similar structure, but they have some special styling needs that set
them apart from the others.  Right now I need to duplicate every selector I
make, which adds up to quite a few in this particular example.  With a
multi-matching combinator I could avoid the duplication.  It would look
something like this:
:any( #top-courses, #additional-courses ) div.chapters h3 { ... }

...with the :any pseudoclass being simple sugar that stands for any of the
selectors contained within it.  :any should accept arbitrary selectors,
separated by commas, since it's basically just performing a simple textual
substitution in the selector.  Though there are surely optimizations that
can be performed, in the simple case all that's needed is for the parser to
transform away the :any and produce two separate selectors to be handed to
the matcher.

It is certainly possible for authors to get the same functionality by going
into the code and adding additional classes.  That's why this is syntax
sugar, not new functionality.  ^_^  Doing such means altering the document
when you just want to save some typing in the stylesheet, and possibly leaks
presentational classes into the document (some times you can certainly come
up with a semantic reason for the class, of course).  As well, style authors
don't always have access to the document source, particularly in cases like
writing up Stylish-like user-stylesheets.


Thoughts on these proposals?  Any ideas for other simple bits of sugar that
would help us authors out?  I'm looking specifically for ones that don't add
new functionality, but rather only shorten the amount of typing we have to
do when writing styles.

~TJ
Received on Thursday, 9 October 2008 15:55:02 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 27 April 2009 13:55:15 GMT