W3C home > Mailing lists > Public > www-style@w3.org > January 2012

Re: @with -- DRY syntax for nesting selectors

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Mon, 9 Jan 2012 09:46:35 -0800
Message-ID: <CAAWBYDCdzxR57HB=AM1t-NBQFsRVeYJ__TMBqtYfzav1EAX0jA@mail.gmail.com>
To: "Marat Tanalin | tanalin.com" <mtanalin@yandex.ru>
Cc: www-style@w3.org
On Mon, Jan 9, 2012 at 5:29 AM, Marat Tanalin | tanalin.com
<mtanalin@yandex.ru> wrote:
> One of features most demanded by web developers is grouping/nesting selectors DRY way.
>
> Current CSS syntax is far from being DRY since it forces web developers to inevitably repeat themselves again and again and again by repeating same parts of selectors multiple times.
>
> I propose following convenient syntax:
>
>    @with (selectors) {
>        rules and @with's
>    }
>
> where:
>    * selectors means a selector or multiple comma-separated selectors;
>    * rules are CSS rules;
>    * @with's are nested @with at-rules.

I've been procrastinating about bringing it up on the list, but Shane
Stephens and I wrote up a document for this as well, based on the
proposal we floated during the Tokyo f2f:
<http://dev.w3.org/csswg/css3-hierarchies/>

This is slightly simpler.  There's no need to alter existing code in
our proposal; rules just nest inside of rules.  To make the parsing
unambiguous, the nesting selector (represented in our proposal as "&")
must be at the start of the nested selectors.

So, for example, your example:

   @with (#example .foo .bar) {
       :this {background: #ccc; }

       :this > DIV,
       :this > P {color: #00f; }

       @with (:this > DIV) {
           :this > A,
           :this > STRONG {font-style: italic; }

           SPAN {color: #a00; }
       }
   }

...would be written in our proposal as:

#example .foo .bar {
  background: #ccc;
  & > div, & > p { color: #00f; }
  & > div {
    & > a, & > strong { font-style: italic; }
    & span { color: #a00; }
  }
}

The advantage of our proposal is that it's more compact and less
visually intrusive than using an at-rule.  The major downside is that
the nesting selector has to come at the front of the nested selectors
to avoid ambiguity (specifically, if you see something like "a:hover
span { ... }", you can't tell whether you're looking at a selector or
a property until you hit the "{").  Using some explicit indicator of
nesting like an at-rule would remove the possibility of ambiguity, and
allow us the more powerful construct of placing the nesting selector
*anywhere* in the selector.

For example, you could use this to apply some default styles for an
element, and then tweak some of them when the element was nested
inside of a particular element:

#example .foo .bar {
  color: blue;
  @nest .baz & {
    text-decoration: underline;
  }
}

~TJ
Received on Monday, 9 January 2012 17:47:30 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:20:48 GMT