Re: Nesting declaration blocks

On Mon, Oct 18, 2010 at 5:31 PM, Bjoern Hoehrmann <derhoermi@gmx.net> wrote:
> * Tab Atkins Jr. wrote:
>>Of course, CSS has a big problem with selector nesting like in my
>>first example - it breaks the core grammar pretty badly.  (It might
>>also require arbitrary lookahead, but I'm not sure of that.)
>>
>>Discussing this around the team recently, though, we hit on a possible
>>solution - @-rules.  I believe that nesting @-rules in a decl block is
>>officially against the core grammar right now, but we discussed this
>>back in the April ftf and kinda-sorta agreed to change this, with the
>>recommendation that @-rules in decl blocks be put at the end, where it
>>would break in a controllable way.
>>
>>Using @-rules, you could introduce nesting with only the minimal
>>grammar breaking we talked about.  It would look something like this:
>>
>>#header {
>>  prop: value;
>>  @nest(img) {
>>    prop: value;
>>  }
>>  @nest(> nav) {
>>    prop: value;
>>    @nest(> ul) {
>>[...]
>
> It seems http://lists.w3.org/Archives/Public/www-style/2004Jan/0018.html
> my proposal for @context is a good bit simpler, it has a nicer name, it
> does not require changing the core syntax, you do not have to put parens
> around the selector-ish thing that sets the context and it allows you to
> use the normal syntax within the at-rule, which makes it easier to embed
> other style sheets (think copy and paste, SSI, or @import, if that's to
> be allowed). For some things you might need an additional rule inside to
> allow for some of the things you are proposing, but then so does your
> proposal (say `@here` optionally followed by a selector-ish thing to key
> the context selector to the current context selector).

Hmm, @context seems pretty similar.  Presumably you could nest them?

One problem I see is that it doesn't seem like you have any ability to
refer to style the current context.  That is, it doesn't look like you
can transform the following:

foo {
  prop1: value1;
}

foo > bar {
  prop2: value2;
}

...into:

@context foo {
  prop1: value1;
  bar {
    prop2: value2;
  }
}

Or do you intend to allow this?

Another problem I see is that it doesn't seem to allow combinators
linking the context with the nested selectors.  It looks like the
nested selectors are automatically interpreted to refer to descendants
of the context, not children or siblings.

Finally, I don't see a good way to use this to clarify an existing
selector, like the "long-selector / long-selector:hover" case I talked
about.


> Now if you had started out with the use cases that should be addressed,
> we could discuss them first and then compare syntax proposals once there
> is agreement what the syntax actually needs to support and how easy it
> should make the various things.

This is purely an authoring convenience feature, so the use-cases are
related to authoring difficulties.  The general case is "make CSS
files less verbose".  In more specifics:

1. When crafting selectors that lean heavily on page structure for
targetting, I often end up with a large number of selectors that have
a common, relatively long prefix.

2. In the above case, I also often gradually descend into the page
structure, starting with "foo", then "foo bar", then "foo bar > baz",
etc.

3. In the above case, I often end up targetting an element with a long
selector, then separately targetting the same element in a specialized
form, with extra classes, pseudoclasses, or pseudoelements.

In each of these three cases, I end up repeating large blocks of my
selector code over and over again, which is very error-prone both on
entry and particularly on edit, where I have to then edit all the
selectors in the same way.


> I am more interested in getting rid of
> all the `.event-definition` in a style sheet such as
>
>  http://www.w3.org/TR/2007/WD-DOM-Level-3-Events-20071221/spec.css
>
> That would require removing all of those and wrapping the tail of the
> style sheet in `@context .event-definition { ... }`. With your syntax
> it's a lot more work and the result would be harder to read and parse.

I don't think the work is significantly different.  Using @context produces:

@context .event-definition {
 th {...}
 table {...}
 th {...}
 td, th {...}
 tr:last-child td {...}
 td {...}
 table {...}
 dt a.noxref {...}
 a {...}
 /* @@@ */
 td {...}
 td b {...}
 dd {...}
}

Using @nest produces:

.event-definition {
 @nest th {...}
 @nest table {...}
 @nest th {...}
 @nest td, th {...}
 @nest tr:last-child td {...}
 @nest td {...}
 @nest table {...}
 @nest dt a.noxref {...}
 @nest a {...}
 /* @@@ */
 @nest td {...}
 @nest td b {...}
 @nest dd {...}
}

@context does win somewhat here, but this particular case is
well-suited for it.  All of the nested bits are solely descendants of
the context; there are no direct styles on .event-definition, nothing
related to .event-definition by another combinator, and no
specializations of .event-definition.

(Interestingly, either structure makes it very obvious that there's
some repeated selectors, a fact which is somewhat less obvious in the
expanded version, due to the noise at the beginning of the selector.)

~TJ

Received on Wednesday, 20 October 2010 19:55:21 UTC