Tech

W3C: CSS Nesting Module for grouping style rules is in progress

[ad_1]

The World Wide Web Consortium (W3C) has published the first working draft for a new module for nesting style rules (CSS Nesting Module). At the current stage as a First Public Working Draft, it is still unclear whether the consortium will finally approve the module and include it in the CSS specifications. The Cascading Style Sheets (CSS) have their own working group (CSS Working Group) within the organization, which introduced the proposal and is now developing it further.

The motivation for the advance is the previously necessary repetition of style-related content. According to the Working Group, the duplicates make the CSS stylesheets confusing and difficult to maintain. The intended nesting option should allow developers to group related style rules. According to the authors of the Working Draft, this makes the stylesheets more readable and easier to maintain.

For example, the following CSS markup could also be displayed more compactly:

table.colortable td {
  text-align:center;
}
table.colortable td.c {
  text-transform:uppercase;
}
table.colortable td:first-child, table.colortable td:first-child+td {
  border:1px solid black;
}
table.colortable th {
  text-align:center;
  background:black;
  color:white;
}

Nesting would group the style rules and make them clearer:

table.colortable {
  & td {
    text-align:center;
    &.c { text-transform:uppercase }
    &:first-child, &:first-child + td { border:1px solid black }
  }
  & th {
    text-align:center;
    background:black;
    color:white;
  }
}

According to the Working Draft, the “nested” style rules behave like normal style rules in that they assign properties to elements using selectors. However, they take over the context of the higher-level selector (parent rule) and can build on the parent selector – without unnecessary repetitions. The syntax currently has a direct nesting and a @nest– Usually planned. A rule marked in this way is only valid within a certain style rule; it loses its validity in other contexts.

With direct nesting, on the other hand, developers write the style rule to be embedded into the parent rule, whereby the selector of this “nested” rule would have to be marked as a prefix (nest-prefixed). In the wording of the Working Draft this means: “A nesting selector must be the first simple selector in the first composite selector of the selector. If the selector consists of a list of selectors, each complex selector in the list must be” nest-fixed “so that the entire (composite) selector is “nest-fixed”. ” (§ 2.1 Direct Nesting)

That sounds complicated, as CSS code it looks like this for valid nestings:

/* & can be used on its own */
.foo {
  color: blue;
  & > .bar { color: red; }
}
/* equivalent to
  .foo { color: blue; }
  .foo > .bar { color: red; }
*/


/* or in a compound selector,
   refining the parent’s selector */
.foo {
  color: blue;
  &.bar { color: red; }
}
/* equivalent to
  .foo { color: blue; }
  .foo.bar { color: red; }
*/

/* multiple selectors in the list must all
   start with & */
.foo, .bar {
  color: blue;
  & + .baz, &.qux { color: red; }
}
/* equivalent to
  .foo, .bar { color: blue; }
  :is(.foo, .bar) + .baz,
  :is(.foo, .bar).qux { color: red; }
*/

/* & can be used multiple times in a single selector */
.foo {
  color: blue;
  & .bar & .baz & .qux { color: red; }
}
/* equivalent to
  .foo { color: blue; }
  .foo .bar .foo .baz .foo .qux { color: red; }
*/

/* Somewhat silly, but can be used all on its own, as well. */
.foo {
  color: blue;
  & { padding: 2ch; }
}
/* equivalent to
  .foo { color: blue; }
  .foo { padding: 2ch; }

  // or

  .foo {
    color: blue;
    padding: 2ch;
  }
*/

/* Again, silly, but can even be doubled up. */
.foo {
  color: blue;
  && { padding: 2ch; }
}
/* equivalent to
  .foo { color: blue; }
  .foo.foo { padding: 2ch; }
*/

/* The parent selector can be arbitrarily complicated */
.error, #404 {
  &:hover > .baz { color: red; }
}
/* equivalent to
  :is(.error, #404):hover > .baz { color: red; }
*/

/* As can the nested selector */
.foo {
  &:is(.bar, &.baz) { color: red; }
}
/* equivalent to
  .foo:is(.bar, .foo.baz) { color: red; }
*/

/* Multiple levels of nesting "stack up" the selectors */
figure {
  margin: 0;

  & > figcaption {
    background: hsl(0 0% 0% / 50%);

    & > p {
      font-size: .9rem;
    }
  }
}
/* equivalent to
  figure { margin: 0; }
  figure > figcaption { background: hsl(0 0% 0% / 50%); }
  figure > figcaption > p { font-size: .9rem; }
*/

Both methods, direct nesting and limited nesting with the @nest-Rule, are equivalent in terms of their functionality. According to the draft, the fact that two rules are required is due to the fact that not everything can be nested in a direct way.