Re: Selector Sugar

On Oct 9, 2008, at 8:53 AM, Tab Atkins Jr. wrote:

> 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

I agree that those would be valuable. There was some discussion back  
in February about "selector variables" (from Jens Meiert) and  
"selector constants" (from me), that were also syntactic sugar for  
selectors. They solved some of the same problems, but your ideas above  
do even better for certain cases. Your #1 above is actually pretty  
similar to how Alan Gresley misunderstood my proposal, which has value  
in its own right:

http://lists.w3.org/Archives/Public/www-style/2008Feb/0145.html

I wonder if it might even be possible to leave out the @scoped, and  
just have it like this to do the same thing:

#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

That would mean that the parser would have to not only look for  
property names inside the curly braces, but also for other selectors.  
And that way, not only is there less to write, but you could include  
styling for the base selector, like this:

#nav-menu {
	border: 2px solid red;
	background-color: blue;
	
	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

Received on Thursday, 9 October 2008 17:11:32 UTC