W3C home > Mailing lists > Public > www-style@w3.org > June 2011

Re: CSS Hierarchies / Selector Nesting Proposal

From: Andrew Fedoniouk <andrew.fedoniouk@live.com>
Date: Wed, 1 Jun 2011 21:08:54 -0700
Message-ID: <BLU165-ds13533B1DC7052AEF344FDBF87C0@phx.gbl>
To: "Tab Atkins Jr." <jackalmage@gmail.com>, "www-style list" <www-style@w3.org>
As far as I understand this:

.slide.image
{
   background-color: red;
    & .credit {  background-color: green; }
}

and these:

  .slide.image {  background-color: red; }
  .slide.image .credit { background-color: green; }

are equivalents.

If "yes" then this was discussed many times already.
I believe that consensus and common advice is to use preprocessors
like http://lesscss.org/ or http://sass-lang.com as you mentioned.

It makes sense to do something like that if you want to
achieve new quality - to have mixins, local [to some sub-tree] style 
systems,
modularity, inheritance and ability to handle arbitrary large style sets in 
CSS.

But for that you will need something like this:

http://www.terrainformatica.com/2010/09/style-sets-in-h-smile-core/

but not just cosmetic changes in syntax.

-- 
Andrew Fedoniouk

http://terrainformatica.com




-----Original Message----- 
From: Tab Atkins Jr.
Sent: Wednesday, June 01, 2011 7:12 PM
To: www-style list
Subject: CSS Hierarchies / Selector Nesting Proposal

We've got an internal effort to try and make webapps and large
webpages easier to write and maintain.  As part of this we want to
develop Variables and Mixins, but another idea we had was that of
Hierarchy, or Selector Nesting.  The idea here is to enable selectors
to be nested within each other, so that instead of writing:

foo {
  prop: val;
  prop: val;
}

foo bar {
  prop: val;
}

you can write:

foo {
  prop: val;
  prop: val;
  & bar {
    prop: val;
  }
}

The advantage of Hierarchies is that you can keep related styles in the same
place, rather than spread across your document, and you can hence more 
clearly
see how various style rules relate to each other. This helps reduce 
cognitive
load on the reader and improves maintainability by taking advantage of CSS's 
{}
scoping.

SASS provides an example of this idea in action
<http://sass-lang.com/tutorial.html#nesting>.

Hierarchies and Mixins work really well together to enable reusable,
hierarchical chunks of CSS to be defined then included in the appropriate
place. Using this approach to define styled widgets avoids many of the 
issues
that traditionally have to be solved via the specificity rules. (See
footnote for an example)

We've considered a few different syntax options, but have settled on
recommending the use of a single '&' character to indicate hierarchical 
scope.
This allows both space-separated and directly adjacent nesting to be 
supported:

foo {
  prop: val;
  & bar {
    prop: val;
  }
  &:hover {
    prop: val;
  }
}

One issue that we've not yet completely resolved is the interaction between
Hierarchies and selector lists.  For example:

foo, bar {
  & far {
    prop: val;
  }
}

Currently we are leaning towards this being supported and equivalent to:

foo far {
  prop: val;
}

bar far {
  prop: val;
}

On the other hand, we are leaning towards only allowing selector lists in
nested selectors via repeated insertion of the '&' character:

foo {
  & bar, & far, &:hover {
    prop: val;
  }
}

With respect to the CSSOM, nested selectors would be exposed as .cssRules
on the CSSStyleRule object, identical to how CSSMediaRule works already.

This feature, as we currently have it imagined, is incompatible with the 
current
Core Syntax.  However, it degrades well in existing browsers if you put the
nested rules below all the properties in a rule.  There is another,
slightly more
verbose, syntax option using @-rules that would only require the same
changes that
Mixins do, where we allow @-rules inside of rules.


FOOTNOTE: Mixins and Hierarchies
--------------------------------

Using Mixins and Hierarchies together, set of nested behaviours can be 
defined
hierarchically, then included where necessary using @mixin.  Keeping the
behaviours defined within a mixin reduces pollution of the CSS namespace and
hence reduces the need to resort to specificity rules.  However, the use of 
a
@mixin allows these rules to be used in the appropriate places:

@trait hover-behaviour {
  foo {
    prop: val;
    prop: val;
    & bar {
      prop: val;
      &:hover {
        prop: val;
        prop: val;
      }
      &:active {
        prop: val;
        prop: val;
      }
    }
  }
}

far {
  @mixin hover-behaviour;
}


FOOTNOTE: Extended Example
--------------------------

Hierarchy looks like unnecessary line-noise when you see only small
examples.  It really shines when you see it in larger examples, like
you'd get in actual applications.  Here's an example from a recent
internal presentation.

This is an actual chunk of CSS taken from the code for a slideshow we
recently wrote:

.slide.image {
  background-repeat: no-repeat;
  background-size: cover;
  background-position: top left;
}
.slide.image .credit                { /*...*/ }
.slide.image .counter               { /*...*/ }
.slide.image section                { /*...*/ }
.slide.image section h1,
.slide.image section h2             { /*...*/ }
.slide.image section.bottomLeft     { /*...*/ }
.slide.image section.bottomRight    { /*...*/ }
.slide.image section.topLeft        { /*...*/ }
.slide.image section.topRight       { /*...*/ }
.slide.image section.topWide        { /*...*/ }
.slide.image section.bottomWide     { /*...*/ }

The duplication is clear and somewhat jarring.  Here's the same thing,
rewritten to use Hierarchy:

.slide.image {
  background-repeat: no-repeat;
  background-size: cover;
  background-position: top left;

  & .credit     { /*...*/ }
  & .counter    { /*...*/ }
  & section     {
    /*...*/

    & h1, & h2      { /*...*/ }
    &.bottomLeft    { /*...*/ }
    &.bottomRight   { /*...*/ }
    &.topLeft       { /*...*/ }
    &.topRight      { /*...*/ }
    &.topWide       { /*...*/ }
    &.bottomWide    { /*...*/ }
  }
}

~TJ
Received on Thursday, 2 June 2011 04:09:24 GMT

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