Hacker News new | past | comments | ask | show | jobs | submit login
WebKit Supports Nested CSS (webkit.org)
519 points by gslin on Feb 16, 2023 | hide | past | favorite | 180 comments



> Back in December, we wrote an article detailing three different options for CSS Nesting.

> Web developers responded to the poll with great clarity. Option 3 won in a landslide.

Yup, pretty much. The only thing I really wish won however was making the beginning "&" always required for nesting. Instead you're able to omit it if there's any other symbol. Example from article:

  main {
   .bar { ... }
   #baz { ...}
   :has(p) { ... }
   ::backdrop { ... }
   [lang|="zh"] { ... }
   \* { ... }
   + article { ... }
   > p { ... }
   ~ main { ... }
  }
The position of requiring & was not represented in the poll but seemed really popular in all the comments and seems like it would only make the parser's job easier (both now and in the future of CSS)

Regardless I'm just happy it's finally here! Hard to see the use-cases for sass in 2024 but, like jQuery, it's definitely made its mark on the history of the development of web standards


Relevant links on this:

https://twitter.com/LeaVerou/status/1580215877705687040, a poll about this specific matter (with links to other relevant polls which on the surface contradict this one).

https://github.com/w3c/csswg-drafts/issues/7834#issuecomment..., on this exact matter (chosen as a convenient starting point, after matters were already settled, but the whole issue is about it). By the time this poll was done, they had already decided not to consider mandatory-&, though I don’t really understand why (it’s pretty obvious to me that dividing into 3a and 3b would have been much more interesting than a couple of the other options which were straw men that no one was capable of taking seriously even if they tried).

https://github.com/w3c/csswg-drafts/issues/7961, about doing away with & in all cases for descendant selector (… which would be terrible for complexity and worst-case performance, and is only being considered because they already made things inconsistent by making & optional in every other case).

(I don’t like where it’s ended up, and consider requiring the & in all cases to be obviously materially superior, for both machine and human handling, and that there’s clear concrete advantage in having the requirement as an actual language rule rather than only a linter-enforced choice. People are far too hung up on exactly Sass syntax.)

> it would only make the parser's job easier

Mind you, it’s not a big difference; it’s just “if there’s no & in the selector, insert one and a descendant combinator at the start” in some shape, which could be as little as half a dozen lines of code net.


It's not a lot of code to implement, but it greatly simplifies usage by eliminating ambiguity:

- Easier for human readers (the "&" is an unmistakable visual indicator)

- Easier for human writers (fewer decisions; there's Only One Way To Do It)

- Easier for syntax colouring


I agree with the rest, but requiring & won’t make it easier for syntax highlighting, because that & can be anywhere in the selector, not just the start; the & affects nothing in determining whether it’s a rule or a property.


I'm saying the "&" should be required _at the start_.

Perhaps controversial, I know. I realize this eliminates use cases like

    em {
      color: green;
      li & {
        color: red;
      }
    }
It's okay not to support these use cases. They're confusing because they break encapsulation; the rule that appears to be nested inside (in this case, color: red) is affected by an element on the outside (in this case, <li>).

Compare:

    li {
      color: blue;
    }
    em {
      color: green;
      li & {
        color: red;
      }
    }
To:

    em {
      color: green;
    }
    li {
      color: blue;
      & em {
        color: red;
      }
    }
The second structure is easier to understand, and in my opinion, the syntax should bias you toward writing it that way.


This functional limitation was eliminated from consideration long ago: it’s very common to want that functionality. There were options considered for still denoting nesting, e.g. start all nested chunks with @nest, but this was decided to be inconveniently verbose. I think & is safe from being inconveniently verbose, but you can’t sanely use that without the functional limitation.

On your example: nesting is not about the sort of encapsulation you think it is—that’s incidental at best. It’s perfectly reasonable to say “this chunk of styles is about <em> elements; and when they’re inside <li>, do this”. The specific example you’ve given is also unrealistic with all three rules touching the same property in this way and two mutually exclusive (that is, li and em cannot both match, in any DOM), and I wouldn’t want it written with nesting at all, but rather like this, for much-increased clarity:

  li {
      color: blue;
  }
  em {
      color: green;
  }
  li em {
      color: red;
  }


Hmm, thanks for the food for thought. In my use of CSS, I rarely come across situations that would call for this, but I'll pay more note to the possibility they might come up.


I remember the main argument against this is that you can always enforce this with a linter and either way it's not a slower parser, maybe slightly more complex.

Personally I do agree and I like the explicitness of always having the &


Yeah that's fair and I admit don't actually know anything about the parsing implications. I guess really I'm just looking for an excuse to convince my coworkers to adopt this practice without coming off like I'm bikeshedding haha


I think you could argue for the clarity (code is read more than written) and consistency (why do I need this here and not in other places?)


> Hard to see the use-cases for sass in 2024

Possibly mixins, loops, and variables, which, unlike CSS variables, can be used in media queries.


>Possibly mixins, loops, and variables, which, unlike CSS variables, can be used in media queries.

Please god no. CSS is intended to be completely declarative. Loops and conditional logic were the very worst ideas SASS ever had.


People want freedom (as seen by the down-votes comment above seems to have gathered) and I do remember the old times when I was very excited for the creativity SASS allowed me.

Then in-between then and now, I did a lot of consulting work, and now I'm strongly feeling that the more DRY you try to make CSS, the more you end up writing, and unmaintainable CSS at that. Random example:

https://github.com/primefaces/primeflex/blob/master/_sass/li...

SASS is too powerful for its own good.

TL;DR: I wholeheartedly agree with the above comment.


yes, mixins. even just static sets of declarations would be a great start, e.g., wanting to apply the same set of base rules to both an entity and various classes without error-prone repetition (which you typically separate to have control over cascading and specificity).

css variables in media queries would be helpful too, but mixins to me is the next big step after :has() (oh so useful, come on firefox!) and this nested css syntax. unfortunately, it may be years for us to see it in browsers. there's no consensus yet on mixin syntax or where in the css lifecycle it would be implemented (there are potentially serious performance implications apparently).


> Hard to see the use-cases for sass in 2024

Modules make writing CSS much less of a naming game. Anything you can do to reduce one of the 2 hardest problems in CS is worth it.


Or build a design system with good names and take advantage of the global nature of standard CSS.


Making sure that the top-level classes of components are unique isn't difficult. Making sure the inner classes are unique (yet still follow a consistent naming convention) is only possible with a methodology like BEM, which is clunky. And you want inner classes to be unique so that you can nest components safely without having outer components accidentally styling the innards of inner components.


How, exactly? Naming aside, splitting things into separate files is often useful, and making the browser fetch multiple files for the base stylesheet is always going to be worse than packing it into a single file.


Global means more reach, local means more specifity. Design systems are global by nature. Has nothing to do with file splitting / packing.


> Web developers responded to the poll with great clarity. Option 3 won in a landslide.

Because there was no “none of the above” option, which developers asked for.


One thing worth noting is that & substitutes for `:is(...)` in spirit under the hood, which means there are some significant behavior differences between native CSS nesting and Sass.

Here's one:

  .foo .bar {
    .baz & {
      color: red;
    }
  }

In Sass, that would compile to:

  .baz .foo .bar {
    color: red;
  }
With native nesting, it effectively compiles to:

  .baz :is(.foo .bar) {
    color: red;
  }
The Sass version matches this DOM structure:

  <div class="baz">
    <div class="foo">
      <div class="bar">
        ...
But the native version matches all of these structures:

  <div class="baz">
    <div class="foo">
      <div class="bar">
        ...
  
  <div class="foo">
    <div class="baz">
      <div class="bar">
        ...

  <div class="foo baz">
    <div class="bar">
      ...
Not a criticism at all (the `:is(...)` behavior is a very useful and welcome enhancement to CSS) but a notable difference worth understanding coming from Sass.


I’ll criticize it.

I recognize this is a preview and I desperately hope this implementation isn’t kept around and treated as a quirk.

This implementation is extremely unintuitive given their explanation of the expected behavior of CSS Nesting and the & symbol.

To quote:

    The & signals to the browser “this is where I want the selector from outside this nest to go”.
Their explanation and the actual implementation result in a majorly different CSS selector.

The implemented functionality, however useful, makes no sense as a default if one can explicitly use :is to achieve this behavior like below.

    .foo .bar {
        .baz :is(&) {
        }
    }
The default should behave like they claim it does; simply replace & with the “outside” selector.


With this hidden :is behavior, migrating to native CSS nesting from SASS will be extremely difficult.


Notably, this is identical to the behavior you get from @scope's nesting, and from passing a complex selector to an `el.querySelector()`.

(We discussed adopting Sass's behavior in <https://github.com/w3c/csswg-drafts/issues/8310#issuecomment...> but ultimately dropped it.)


Agree important to note the difference but I personally prefer the nested CSS behavior. Much more sensible to use `&` as a logical operator


Nested rules is just a syntax sugar.

In Sciter, 10 years ago, I came up with style sets:

    @set Main {
      :root { ... } // root element that has this set applied 
      .bar { ... } 
      article { ... } 
      :root > article { ... } 
    }

    main { style-set: Main; } // main element with the set applied 
This solution solves two problems:

1. Modular/componentized style definition - same goal as in nesting styles, but without introduction of new syntax constructs.

2. Reduces CSS resolution load. Rules inside the set are scanned only for DOM children that have style set defined.

3. DOM element may have @styleset="url#name" attribute defined - used in components (Web alike components and React alike components)


If syntactic sugar was really just sugar, JS would have sticked to callback functions, and we’d still be inventing abstractions to make our lives easier.

Syntactic sugar, sometimes, is the promise of sunnier mornings and that matters.


"For a Linux user, you can already build such a system yourself quite trivially by getting an FTP account, mounting it locally with curlftpfs, and then using SVN or CVS on the mounted filesystem. From Windows or Mac, this FTP account could be accessed through built-in software."


For those that do not know what this refers to: https://news.ycombinator.com/item?id=8863


Solid reference


Well, that's the matter of live systems design.

When you want to add a feature you should ask first if that can be accomplished by existing mechanisms.

And the second, if to go with with the change that affect millions of users, can we solve not just one problem (that already has a solution like LeSS & Co.) but possibly other principal too?

So for #1. If we already have @media sections, why not to use the same notation?

   @media name { ...rules... }
and

   @set name { ...rules... } 
@set can use existing code in parsers. Not just in browsers but in tons of existing tools and editors that do syntax highlighting.

And #2. Style sets solve problem of global CSS namespace pollution.

Consider this rule:

   div [name="some"] { ... }
then, while calculating styles of DOM elements, absolutely all N DOM elements need to be checked against this rule. So it is a O(N) complex task. And proposed nested rules thing does not reduce the N, but may make this even worse - more rules will be used.

While in style set solution:

   @set ComponentA {
      div [name="some"] { ... }
   } 
that rule will be checked only against children of componentA - the rule is local/scoped to DOM subtree. Still O(n), but n <<< N.


Contemporary CSS engines use bucketing, so a rule like div[name="some"] will only ever be considered for something that has (depending on your browser implementation) either a “name” attribute or is a <div>. In other words, “Absolutely all N DOM elements need to be checked” is completely wrong. It's worst-case O(n), sure, but on a practical page nowhere near average-case O(n).

As for @media queries, I can't say anything about Gecko or WebKit, but at least in Blink they're handled entirely different. And @scope (which is the closest I know of to your hypothetical @set) is significantly less efficient than bucketing is, or even a simple parent selector, since it needs to walk up the DOM after the rule matched.


> bucketing ...

"All of that is very different between the various engines, making the whole process even less predictable."

Source: https://benfrain.com/css-performance-revisited-selectors-blo...

In worst case complexity of styles resolution is O(nS*nD) where nS is a number of style rules and nD is a number of DOM elements. That's for current flat style table used by CSS. You can optimize bits and cases but it in general problem is like that.

> @media queries ... at least in Blink they're handled entirely different.

@media and @set are different mechanisms. :root in @set matches element that has this set applied. @set's are scoped set of rules. @media are not.

But I was talking about different thing - parsing, in particular in syntax highlighters and other tools.

----

Consider this DOM:

   <body>
     <aside styleset="styles.css#aside-set">...</aside>
     <main styleset="styles.css#main-set">...</main>
   </body>
And CSS:

   @set aside-set {
     :root {...}
     ... nA more rules
   }

   @set main-set {
     :root {...}
     ... nM more rules
   }
 
<aside> content style resolution will always be constant and independent from <main>, no matter how many nM rules you will have. While currently (with the flat table) adding rules for <main> content will increase complexity of <aside> DOM resolution too.

As a bonus: rules in two sets are completely isolated. Adding rule in main-set will never break existing aside design.


> In worst case complexity of styles resolution is O(nS*nD) where nS is a number of style rules and nD is a number of DOM elements. That's for current flat style table used by CSS. You can optimize bits and cases but it in general problem is like that.

Worst-case isn't really interesting for browsers, though. CSS doesn't have an adversarial performance model.

> @media and @set are different mechanisms. :root in @set matches element that has this set applied. @set's are scoped set of rules. @media are not.

Again, this roughly matches @scope (where :scope matches the element that has the given selector applied). But this is just a fantasy spec, right? There are no browsers that implement this, and just like with @scope or nesting or CSS at all, there's no guarantee in the spec what performance characteristics you would have?

FWIW, if you want something like this and get it through CSSWG, you'll most likely see it end up with worse performance than flat CSS, unless it becomes _really_ popular and browsers see the need to optimize certain sub-cases of it (the general case, with tons of different sets, will be nearly impossible to make really fast).


unpopular opinion I'm sure from reading everyone here, but to me nesting css is syntactic poison - or maybe syntactic sucrose or something that gives you cancer you use too much of it?

Anyway programmers given nesting just do it all the time which ends up leading to stuff like

article.news section.preamble h1 and probably a few other selectors after that all nested giving you a wonderful high priority for your style and possible collisions.

Then the same guys who made the problem can't figure out the problem so they figure some highlevel nesting is the solution so there won't be any collisions and overriding of styles.


I’ve seen this plenty of times in CSS codebases. Nesting is a write-time optimisation but a read-time hinderance.

If users stick to nesting for lightweight scoping, things will go well. But they wont: they’ll use it to DRY every possible line and their inheritors will suffer dehydration.


not just read-time, but yes it is that as well, I find a class I search for this class, now I need to understand all scope in html tree and scope of the css to understand am I looking at the right one (sure you can run into situations with that as well, but in my experience nesting makes it more difficult)

but it is also a source of bugs, because complicated selectors mess with css priority and the cascade then someone writes something that has side effects and blame CSS instead of their ridiculously long nesting.


Well yes, nesting is inherently a concretion that can lead to overly specific selectors. One of our/my style guide rules is to avoid nesting (in SCSS) when it's unnecessary. When nesting is used it should read "this declaration only makes sense in this nested context".

But not having nesting at all is similarly problematic as having too much nesting, because it can lead to repetition, proliferation of classes and brittleness.


I agree with you.

I worked in several codebase that used SCSS and due to those little hacks popping up in review, every time we ended up putting a "rule" in place to stick to two levels of nesting at most, or 3 if you're using the third nesting-level for pseudo-selectors (:hover :before etc). And this rule very rarely had to be broken, as it was extremely easy to avoid being too clever with nesting. (Of course, if there was a real good technical reason, we'd "break" it too).


Yup, I had a stylelint rule specifying no more than 2 levels.


> Nested rules is just a syntax sugar.

But this syntax can also be used in minified CSS. I'm sure minifiers will have a fun time with this in 5 years when most of the major browsers support it.

I've seen all sorts of examples of stylesheets that would benefit from this, Tailwind Typography being a good one because it styles all sorts of nested elements but only inside of `.prose`. Eliminating tens or hundreds of `.prose` selectors by wrapping them all in a single `.prose { }` would make it smaller; not sure exactly how much smaller though.

This sounds like a fun case study.


Maybe I am an outlier... but I really don't like nested style documents like those founds with SASS, LESS, PostCSS. When the number of nested selectors becomes too great it can become very difficult to reason about. I would never use this without some kind of lint rule enforcing a maximum depth of selector nesting. I agree with the other commenters ITT taking the position flat CSS looks cleaner than nested documents.


The difficulty you mention is definitely an issue, but the insane repetition required for even a modestly complex piece of UI when using "flat" CSS is worse, in my opinion. I suppose there might even be a slight efficiency gain over the wire once Sass outputs nested CSS by default.


I wrote flat CSS for many years and yeah it's a lot of work but also I find it becomes more difficult to parse visually.

Like when writing HTML or regular code, I find indentation helps me parse and navigate the structure very easily.

There are cases with complex components where it can become a bit complex, but it's trivial to split the tree in multiple parts to reduce the indentation.


I agree: even when I use preprocessors, I rarely nest “normal” selectors. The real win is nesting pseudoselectors (:hover, :focus, etc) and media queries.


You should use stylelint anyway and then you can set `max-nesting-depth`

https://stylelint.io/user-guide/rules/max-nesting-depth/

I mean, these days almost every JS developer use some kind of linter - why would you not use a linter for CSS? Literally nothing to lose since you can set the rules as relaxed as you want.

PS: I set it to 3 - Using good convention like SuitCSS I have never found I needed more nesting. Usually you think about a problem and find a simpler way to do it.

https://github.com/suitcss/suit/blob/master/doc/naming-conve...

TLDR If you use any of the good practices for CSS such as BEM or BEM-like you don't have lots of nesting anyway.

And I like how the article mentions as an example `ul article ul` and how to solve it by adding a symbol :is() to be able to nest, and it's literally the one thing you don't want to do anyway, which is a selector like `ul article ul` (as per BEM methodology). Instead `.list .article .article-list` as a veyr poor example doesn´t need the special "fix" the article mentions.


I generally only nest one level down, and at most two. Any more and, as you say, it becomes very convoluted, particularly when it comes to specificity. However, alongside pseudo elements, the killer feature for me is that nesting enables namespacing for components, which (a) leads to much simpler class names that makes CSS much easier to read and (b) stops a great deal of repetition of the class on the wrapper element.


> When the number of nested selectors becomes too great it can become very difficult to reason about.

This is a sign you need to decompose whatever design you are working on into smaller components. If you’re trying to write styles for a whole page at once, you’ll see this problem, but if you are working on small components, it’s very rare.


> decompose whatever design you are working on into smaller components

I haven't followed modern CSS development much. Does it have a module system now?


Not precisely a module system, but you at-least get scoping if you use web-components where you can restrict CSS to the scope of the web component. (There are CSS module systems, but they are not covered by a standard and use JS libs)

The problem is that web-components need JS enabled, which really, really sucks. Why should a component that can perfectly render itself using plain HTML and CSS need to have associated JS declaring: "Hey! I am a web-component!". Declarative web components would have made adoption of web-components super-high , but alas, corporate interests are against this feature.


If you give a junior front end developer CSS nesting, you can get some very janky results.

Working with SCSS codebases and junior developers, I've seen SCSS nesting get so bad, the line order of the selector in the stylesheet would determine what styling gets used.

Nesting CSS is useful in some cases, but for the majority of use cases it can get unwieldy very quickly.


When the number of nested selectors becomes too great it can become very difficult to reason about.

When any complexity becomes too much it makes it harder to reason about. The solution is to avoid complexity; you can do that while using a small number of nested selectors.


It’s Sass & Less, not SASS & LESS. Less is sometimes stylized with all caps (or all lower like {less}) and is an acronym for Leaner Style Sheets, but Sass was never was stylized with all caps nor is it an acronym.


This is great! The only reason I use SCSS is for the nesting. It should have been implemented 10 years ago, but better late then never.


It's great that parts of SCSS are getting superseded by CSS.

Nesting is great to avoid selector repetition.

Custom properties (CSS variables) and CSS functions give us tools to avoid magic numbers and to encode layout relationships.

New sets of selectors and container queries let us decouple and re-use declarations more.

CSS Houdini gives us further power in extending CSS functionality.

Of course there are things that SCSS provides which are unlikely in the scope of future CSS proposals such as datastructures (maps) and loops to generate classes and mixins. But I can already imagine a world were those aren't necessary anymore for many cases.


> SCSS are getting superseded by CSS.

Reminds me of how Coffeescript died out because its best ideas got integrated into Javascript.

What I want to know is: how the hell did this take so long? Nesting is such an obviously useful feature to have in CSS, and once I'd experienced it in SASS I never wanted to be without it. Why did it take 10+ years for this to be introduced to CSS, especially when other browser-based technologies like JS have evolved enormously in that time?


Some of the Less/Sass maintainers are also active parts of the communities that write the specs and I guess when the idea of nesting was fresh to these preprocessors they didn't feel compelled to make it a core part of css with how widely the preprocessors were getting adopted. While I don't doubt our computers 10+ years ago could parse through nested styles it's probably really trivial now and thus being implemented into core.

As far as the speed of which things get implemented, I often feel there is a lack of understanding where design and development overlaps. Most devs are just devs in the sense they solve algorithmic/browser rendering problems, and don't really dabble enough with markup/styling languages like HTML and CSS to hit the pain points of using them. And the people that deal with markup/styling do not know the proper channels to rally behind some of the ideas that would make their lives easier. Unfortunately, there are less individuals that are proficient at markup, styling, and programming (not just in the sense of coding in JS/TS, but understanding the internals of the browser and programming for it), and the unicorns that do understand are often snatched up by Google/Microsoft/etc. which often have their own agendas. I feel there's just a lot more niche backdrop knowledge that is required to get the ball rolling. These are just my feelings on this matter, I could be wrong.


For another take: I try to write a single module.css file per component in which I do zero nesting, avoiding any preprocessors (other than postcss modules, obviously). Nesting, IMHO, makes CSS a bit easier to write but much harder to read.


For me this is where something like PostCSS shines. You simply write future css and remove the plugin when it’s supported natively.

This wins in my opinion because there shouldn’t be any conversion necessary from something like Sass to CSS


What's the hit/miss rate on that CSS changing syntax?

I Vaguely recall something similar happening with decorator syntax/how it worked in JS/typescript.

Or do you keep to CSS features that are locked down in terms of spec, just waiting on implementation to roll out?


That decorator syntax thing was a mess. The original syntax seemed like it was far enough along. Many folks adopted it because it seemed like "a sure thing". I ended up pulling it from a project in 2017 because so few of the folks on my team wanted to truly understand what problem those were meant to solve. It was easier to "decorate" in a more manual way (wrapping a function with a function).

The way TC39 handles stages now should stop things like that from happening. (You implement a Stage 1 or 2 feature fully knowing it could change)


It’s your call fortunately/unfortunately.

The safe option is obviously to install plugins for features that are close to passing as possible, where the api is stable at least - but there are plugins for very early stage proposals too.


Awesome to finally have nesting. The way I see it, this took 10 years longer than it should have.

I feel the only big thing missing from the vanilla stack for me right now is a template element that multiple html files can share. Just like how you make a blog header in Jekyll or Hugo and it adds it on all your blog posts get the header. I haven't found an easy way of doing that if I have a bunch of html pages.


That's what an iframe is? I guess there could be a partial element that works like <partial href="header.html" /> but if it's referencing HTML, what about JavaScript or CSS it includes? That's exactly what iframe handles.


What you're asking for is called Server-Side Includes, it's been a feature of Apache for ages, but is also supported by Nginx and other servers.


We had it briefly in the form of HTML imports, but the powers that be removed it because it’s not powerful enough for JavaScript/web apps development; totally ignoring the fact that the web isn’t just about apps.


well, the classic solution has always been to use an iframe :p


I don't know if that's actually an ok method or not, but I thought of that and looked around for it with little luck


Not implemented in Firefox yet, but they like it: https://github.com/mozilla/standards-positions/issues/695

They're tracking work in https://bugzilla.mozilla.org/show_bug.cgi?id=1648037


Will nested CSS support mixing properties and nested rules in any order, or do all the nested rules have to grouped together at the end? Right now, I frequently write SCSS rules like this:

  .some-class {
      background: blue;
      &:hover {background: red}
      border: 1px solid;
      &:active {border: 1px dashed}
      padding: 16px;

      display: flex;
      gap: 8px;
      
      & > * {
          color: red;
      }
  }
And it would be a pity if that wasn't allowed.

The reason I ask is because I seem to remember an early proposal not allowing this, but I can't find where I read it.


As I understand it, you can mix it but the parser will hoist all the immediate some-class styles to the top


Why would it not support it?


I don't know, that's why I'm asking.


lol just curious what the thought process is. Sass and postcss support that and every other css flavor with nesting I've used supports it and it seems like it'd be a pretty big deal and something that would be explicitly called out in the article if it didn't support it. So I'm just curious if you've run into an issue with that or if there's some in-the-weeds technical reason why that might not be supported


My memory was correct. I found the section in the original proposal[1] that did not allow mixing nested rules and declarations:

> When a style rule contains both declarations and nested style rules or nested conditional group rules, the declarations must come first, followed by the nested rules. Declarations occuring[sic] after a nested rule are invalid and ignored.

[1] https://www.w3.org/TR/2021/WD-css-nesting-1-20210831/#mixing

Fortunately, this has been changed in the most recent proposal[2]:

> When a style rule contains both declarations and nested style rules or nested conditional group rules, all three can be arbitrarily mixed. However, the relative order of declarations vs other rules is not preserved in any way.

[2] https://www.w3.org/TR/css-nesting-1/#mixing


Very interesting and exactly what I was curious about! Thanks for the links

Really curious about the reasoning behind that initial quirk


Depending on the exact parsing strategy it might be genuinely required (such as if the parser switches from "property mode" to "rule mode" at some point), but in this case it was just because it's kinda confusing to do so.

We removed the restriction, but still warn against it due to readability issues.


"CSS Nesting will work just like Sass, but with one new rule: you must make sure the nested selector always starts with a symbol."

I think I like it. In general I like the adoption of good features like this. But. It's getting awfully hard to keep track of CSS vs SASS syntax. Starting a greenfield project today I'd leave SASS out of it... but I'm usually working on projects where SASS is already present. Shrug.


At this point, I'm using SASS pretty much exclusively for nesting (and where required to customize other styling systems-- mostly older Bootstrap). Once I can assume CSS nesting is everywhere I need it, I can probably eliminate SASS in most places where I'm using it.

(I'd also like more/better color functions out of vanilla CSS. But that's not necessarily a dealbreaker for me in most cases.)


I would recommend using PostCSS. It allows you to compile future CSS for browsers today. When you feel comfortable with browser support you can just remove the processing step


https://caniuse.com/css-nesting

So it's the latest chrome, Safari technical preview, and edge behind a flag. No disposition from Firefox yet afaict.


Mozilla has come out on support of the standard but I'm not seeing much on the Bugzilla tracker. May be a while until it's supported, especially since modifications like these also impact functionality like the syntax highlighter and the dev tools.


Chrome dev. The latest stable version is 110


Can someone explain why parsers can't handle nested selectors which don't start with a symbol?

I've written plenty of parsers (recursive descent, packrat, Pratt, and using generators) and not a single one would have any trouble parsing something like:

    html {
      body:has(p) {
        width: 1000px;
      }
    }
The only thing I can think of is that they are trying to avoid a lookahead, i.e. you have selectors like "body:has(p) {" which initially look like they could be setting a "body" attribute to the value "has" until you reach the "(". But these lookaheads aren't hard to implement in practice. There are performance issues if the lookahead has to go too deep, but CSS developers can use the & in those cases as an optimization, and you could limit lookahead depth to something like 256 (which would handle the vast majority of non-malicious use cases).

Perhaps the lookahead has a lot more drastic effect than I'm expecting on performance for short lookaheads, but I'd like to at least see some profiling of that, as it seems to me like this possibility was discarded without much consideration or explanation (it wasn't even included in the poll).

There's also another way to do this without lookaheads at all, by building up a structure for each potential path and then discarding the one that doesn't complete (I think this is basically a DFA but it's been a while since I read literature on this so I'm forgetting the terminology). This would probably avoid the performance issues but also probably be a larger departure from the current implementation of the parsers.


See https://github.com/w3c/csswg-drafts/issues/7961, which details some of the problems, including genuine and currently irreconcilable ambiguities, and goes into attempting to make it work by adding convoluted and complex rules and arbitrary lookahead in a way that I really strongly hope gets nixed because it’s awful. (And they’re really only trying to do this because they resolved to make & optional in #7834, which I think was where things started going wrong.)


Sorry, all the irreconcilable ambiguities are conflicts with other, not-yet-accepted proposals, with one exception, a conflict with JS tools that use JSON to spit out CSS. I'd argue that there are other syntax options for those other not-yet-accepted proposals, and this is likely to be a more-used feature than any I saw. And forcing some poorly-designed JS tools to come up with a minor workaround just isn't something I care about.

Is there any conflict with anything that exists in the standard right now?


The parsing time issue is "in the standard now". Even if no rule today matches `property: value { something in brackets }`, that's still at least three tokens (`property`, ':', 'value') to read before bailing out at a bad "property" because values "shouldn't" have things in brackets. (You can build examples with complex CSS selectors where it becomes way more than 3 tokens, as well.)

CSS was designed to be "forgiving" of malformed input, so there's generally no "early" bailout the parser can make, even if it doesn't think it knows which property you are talking about and has a whitelist of specific properties it supports.


Indeed, the reason is simply to keep the current look-ahead(1) for the CSS syntax. If you allow nested rules with selector list which doesn't start with a symbol, you need (in theory) an unbounded look-ahead.

However, the current spec has been written in a way that it doesn't prevent removing this restriction in the future. But the CSSWG would prefer to have some real world profiling data to know the actual performance cost of removing this restriction.


Whenever I see nested CSS, I always think the non-nested version is cleaner.

Then again, I'm lucky enough to often work with my own 'hand-crafted', semantic html, and not some div soup generated by a tool.


I generally agree and wince at anything deeply nested, but there's no question that the biggest benefit here by far will be pseudoclasses. Especially when you wanna do something to children elements based on a pseudoclass

  .page form
    border: 2px solid #223;
    border-radius: 0.15rem;

    & button {
      background-color: red;
      transition: background-color 0.15s ease;
    }

    &:hover button {
      background-color: blue;
    }
  }
seems way cleaner, easier to read, and more maintainable than the alternative which I don't even wanna type out


Yeah I agree. Most of my CSS files end up feeling like a big, append-only list of selectors for seemingly random stuff. Its so hard to tell if there are selectors in there that are no longer in use.

I really like the look of nested selectors for this reason - because I can group my selectors by component.


You could always use tailwind - the problem of CSS classes no longer in use is the exact use case for it.


Am I missing something… isn’t it just a simple substitution?

    .page form {
      border: 2px solid #223;
      border-radius: 0.15rem;
    }

    .page form button {
      background-color: red;
      transition: background-color 0.15s ease;
    }

    .page form:hover button {
      background-color: blue;
    }


Yes it's terrible. Not just that you have to type ".page form" 3 times, but that you don't have a convenient way to group together these bits of style that clearly are meant to go together

Imagine those three rules in a 200 line CSS file.


That’s the point. Why should we be doing the trivial substitution if tools can do that for us!?


You are forgetting that it will also make files smaller. I tested here, and it reduced from 172b to 160b, on minified versions. Bigger files will have a bigger reduction on file size.


Any way to turn the second use of `button` into a second level of nesting there?

E: or would you have to use `>` somehow?


This won’t kill Sass/scss. Compilers will still be useful for many reasons, I see those compilers targeting new standards instead. Also, bummer that nested rules made it but <style scoped> was removed. The only viable option for me today to keep a maintainable css code base is to use a css in js solution and a compiler. In fact I don’t see why all this excitement for native features, if all you need could be just a capable compiler(bundling, minification, optimization, dead code elimination etc.)


Sanity has prevailed! Great work from the WebKit team, leading the way here. Not to mention great solve on the `color: blue` fiasco. Balances an edge-case compromise nicely, and leaves it open to future improvements. Bravo.


What is the `color: blue` fiasco?


Writing from memory here, please correct as required, but one of the major concerns with scss style syntax was that it was "undesirable" for interpreters to differentiate between tag names and properties due to legacy CSS token-parsing techniques and the performance concerns around "infinite" lookahead ("controversial"). `color` is one example (possibly the only example) of CSS property / tag name overlap which makes the scss style syntax `tag { color:hover { color:blue } }` slightly ambiguous and potentially tricky to parse.


Fwiw, while I deeply appreciate WebKit supporting the proposal as well, the editors of the Nesting spec are Googlers and the Chrome impl happened at the same time.


Worth a lot! Thanks for clarifying. You need to give your product manager / blog team a kick :)


Related:

Help choose the syntax for CSS Nesting - https://news.ycombinator.com/item?id=34006622 - Dec 2022 (159 comments)

Updated CSS Nesting Syntax to Avoid Common Copy-and-Paste Errors - https://news.ycombinator.com/item?id=33537539 - Nov 2022 (1 comment)

CSS Nesting - https://news.ycombinator.com/item?id=33424361 - Nov 2022 (2 comments)

Help pick a syntax for CSS nesting - https://news.ycombinator.com/item?id=32248419 - July 2022 (240 comments)

CSS Nesting Module - https://news.ycombinator.com/item?id=28375596 - Sept 2021 (71 comments)

CSS Nesting Module - W3C Editor’s Draft - https://news.ycombinator.com/item?id=27684332 - June 2021 (1 comment)

You Probably Shouldn't Be Nesting Your CSS - https://news.ycombinator.com/item?id=6583109 - Oct 2013 (1 comment)

WebKit to get CSS variables, mixins, nesting? - https://news.ycombinator.com/item?id=2111510 - Jan 2011 (6 comments)


man I can't wait to not need LESS/SCSS anymore. the less I need to compile/transpile before handing stuff off to the browser, the better in my book.


I’m looking forward to the day when we can get back to no compiling/transpiling web development.


I'm afraid TypeScript support in browsers is very far away, if it ever happens.


JSDoc type annotations look good though, and TS can work with them: https://www.typescriptlang.org/docs/handbook/jsdoc-supported...


There's not much of a point. It'd just slow movement on Typescript itself. Unless of course fast-moving, transpiled Typescript started being transpiled to browser-acceptable Typescript, i.e. transpiled back enough to where most browsers can parse it. But at that point, why not just do it the way we're currently doing it, targeting JavaScript? Also it'd just make web dev even more confusing for newcomers than it already is.

I don't really see an issue with treating JavaScript as something of an "assembly of the browser," in that anyone can make their own language and target it.


I don't understand this viewpoint, but I've seen it a lot so you're definitely not alone. A large part of what's useful about SASS are the mixins and functions, not just nesting - do you just not use those?


No no I do, I just don’t want to use a CSS pre processor to utilize them. I want them to be part of vanilla CSS, same as variables are now, same as nesting is now.


Yup. But currently they offer more as variables and nesting. Templates, Subroutines, etc.

Value manipulation (like color changes) are possible in css, but complicated to write and read.


I guess minification is still a good idea? Or is this now irrelevant with gzip everywhere?


I don't know anything about WebKit development processes or community management, so please forgive me if I say something wrong.

Isn't it interesting how the engine has been implementing new features and generally running on a lot of steam coincidentally since the EU's Digital Markets Act (which will force other web engines on iOS) went into effect?

Or maybe the dev process and community interactions has always been like this, in which case disregard what I just said and feel free to correct me.


Didn't it go into effect in September 2022?

Safari took a leading role in interop-2022[0] from the very start. So the change in Safari's philosophy stretches back at least to start of 2022, but they've also led the way on adoption of a number of other web standards like the new colorspaces which they've had since 2021 and which Edge and Firefox still don't support (well, FF has a feature flag)

[0] https://wpt.fyi/interop-2022


Historically the webkit team has pushed the web possibilities a lot. Just take a look at the amount of APIs that you had to add the `webkit` prefix, for example. Not sure if you work with browsers, but constantly you meet something that they implemented first.

I honestly think that developers are very wrong when they think that Safari/webkit is slowing the web down. Yes, some things like lack of notifications etc are very annoying, and they could've been implemented. But I still prefer this approach over the Blink one, where they develop half-baked ideas just to track you better.


It's not just getting those features implemented, but also shipping those to the user. Safari is the only browser that doesn't have autoupdate and has versions tied an operating system in 2023 and that's one of the biggest problems.

While you can be happy only supporting say the last version of all other browsers, Safari requires you to give it years before the marketshare of the new versions are enough that you can migrate to new features, thus making the fact that webkit had implemented those features first completely irrelevant.

Furthermore, the fact it only runs macOS makes it a true pain in the ass to test, you need to have access to an apple machine to test it, be it virtualized or remote, which sucks because even Edge has support for Linux at this point.

Even worse is the fact that there are indeed a lot of features Apple simply refuses to implement, specially related to PWAs, which has slowed down the adoption of PWAs by at least 20 years, ane that's if they ever make a comeback after the crippling Apple did to them to maintain App Store supremacy.

I could go on and on and on and on. Webkit is great sometimes, but Safari absolutely sucks and has been slowing down web development ever since IE stopped being a problem for most developers.


Funnily enough they JUST released a blog post talking about how they are going to improve some of these missing PWA functionalities at:

https://webkit.org/blog/13878/web-push-for-web-apps-on-ios-a...

https://news.ycombinator.com/item?id=34823402


Doesn't sound interesting to me. Safari also implemented a very popular feature first a year ago, long before that act (:has() selector).

Even if Safari were to be the best browser ever, I don’t think that would save Apple, so any development effort would be futile (especially compared to lobbying)


That's a valuable addition, but it's unfortunate that it arrived late. These days, functional CSS http://minid.net/2019/04/07/the-css-utilitarian-methodology/ is gaining popularity due to its effectiveness in reducing the need for excessive nesting of classes and unwieldy CSS files.


Functional/atomic css is great. But there are many use cases for composing and refactoring them into aggregates. Nested css can help you for tgese cases.


The more you rely on CSS to change the visuals based on situations, the worst to main in the future. It's an option, that's good, but for me it's been years that I don't go back to that anymore.


Is there a PostCSS or similar plugin which enforces this nesting syntax (& required for element selectors) so we can be ready for when this is widely adopted?


PostCSS has supported CSS nesting for many years now. The nesting standard has changed pretty minimally over the years and the PostCSS team has done an excellent job keeping up

One of the main reasons I never used CRA for my miniprojects was because the first thing I always wanted to do was set PostCSS up with nested CSS support which was a pain to do in CRA


What do you use now? I'm currently using Create-React-App for one of my projects and some parts of it are really frustrating. For example, you can't create a Web Worker script without ejecting, or using some tool that intercepts and alters the CRA Webpack configuration.

Should I just bite the bullet and figure out Webpack (or another bundler) from the basics? I feel like that will be inevitable at some point anyway.


Tbh nowadays I use every new project as an opportunity to try something new. I'm in between a Fresh project, a Svelte project, a PWABuilder project, and a Qwik project. They all have their use-cases and {dis-}advantages so it's nice to know a lot of different tools for different jobs

But I've realized a lot of my projects can actually get by pretty far with just vanilla html/css/js and a good reset.css so I have a template for that that I continuously update and I've actually found that to be the most productive. Though that's likely a function of not having to learn something new unlike all my other projects

There's been suggestions on the React repo of dropping the suggestion to use CRA from the docs entirely since it's pretty outdated and not really in keeping with React's current philosophies.


IMO, ESBuild is the best option these days. It’s not as magic or batteries included as Webpack, but there’s very little kept secret from you during the compilation process. It’s fast too!

Another tricky alternative is to just use TypeScript’s compiler. Combined with the new import maps spec, you can target most modern browsers and skip bundling all together.


I'd actually recommend Vite over Esbuild directly. It uses Esbuild under the hood, at least for production builds, but during development it uses the native import syntax with some optimisations to bundle dependencies together somewhat. This gives you a really quick development build, and then a well-optimised but still pretty quick production build.

But I think the real benefit is that it's much easier to get right than Webpack ever was. You don't need to start by configuring a thousand different plugins, rather, you just write an index.html file, reference the root CSS and JS file from there, and then it can figure out the rest, including all the optimisation/minification details, applying Babel, autoprefixing, using browserslist, etc. If it doesn't recognise a file (e.g. because you're importing a .vue or .svelte file) then it'll recommend the right plugin to parse that syntax, and then it's just a case of adding the plugin to a config file and it'll work.

I'm a big fan of Parcel, which is a very similar tool for zero-configuration builds, but Vite feels significantly more polished.


I agree - I love esbuild, but Vite is great and will generally give you what you want and more with minimal hassle. The development server and hot reloading are excellent.

I did recently find one thing that didn’t work out of the box in Vite, though. I needed to write a web worker, but Vite didn’t package it into a single .js file, so I had to call esbuild directly to do that.


Safari supports import maps in TP https://caniuse.com/import-maps


I’m familiar with PostCSS nesting, but I don’t think it requires ampersands (&) for nested element selectors: `.class { p { ... }}` works. I’m having trouble finding a canonical name for the standard flavor of nesting, otherwise I’d be looking for a GitHub issue.


I am not a big fan of nesting. I have yet to see a codebase where nesting makes CSS more readable. Even with BEM, I find it easier to reason about (and debug) the vanilla style. However, I must admit that `&:hover{}` does have a certain appeal. Also, I am very happy that nesting can be done without tooling in the future. It's a feature that many people love.


I agree, for some reason my brain sees the non-nested versions of CSS as more readable. Although we seem to be in the minority here. Very open to trying out nesting and perhaps my brain will 'flip' to eventually prefer it.


it comes down to the Inspector for me. I've had zero problems thus far right clicking on elements and then clicking on the relevant CSS exposed. I don't think anyone should actually be reading through CSS docs (will admit I'm a solo dev here so got it easy), and I'm afraid this could make the Inspector more confusing.

furthermore I suspect a very large % of people do not realize you can actually edit and save your CSS directly with Workspaces.


This is an excellent step forward for css, and frankly it's nice to see safari take the lead for a change rather than lag behind.

It'll be about a year or so before I'm comfortable using it in production code (assuming it comes to Firefox soon, and presuming it'll get into Edge by default.)

But a year goes past quickly these days, and at least the clock has started ticking.


I am supportive of this. Ofc, parent selector would still be nice, but I understand the problems solving that performantly.

As a highlight, Nested CSS doesn't support nested selectors if they both begin with letters, so the "&" is used as divider.

I highly recommend web-dev's check out the last section of the article*: https://webkit.org/blog/13813/try-css-nesting-today-in-safar...

[*: even though, IMO, in this instance it seems like a hack; nesting CSS styles, while the HTML is nested in the opposite direction seems pretty counterintuitive. but having the tool in your toolbox could be useful for other things.]


Do you know about the `:has()` pseudo-selector? It is basically a parent selector, and has decent browser support already!

* https://developer.mozilla.org/en-US/docs/Web/CSS/:has


We have a parent selector. It's called :has(), and Firefox is the only holdout at this point.


You can enable it with a flag in Firefox though. If only I could enable subgrid with a Blink flag though ha.


You can enable :has in Firefox, but it's buggy and still very experimental at this point. Or at least it was a month or so ago.


The flag you're looking for is --enable-blink-features=LayoutNGSubgrid, I assume.


    :is(article) &
That looks hacky at best.

The excuse of parsing performance is responsible for so much weird syntax in web standards today. The standards are literally being dragged around by browser vendors' priorities.

I wish they would do it the other way around for once: come up with the cleanest, easiest-for-humans syntax as possible, and tell browser vendors to fix their damn engines. Perhaps this will lead to the development of a new CSS engine that's actually optimized for the latest goodies.

Instead, for the last decade or so, we've only been getting bits and pieces of half-assed imitations of Sass. Better than nothing, of course, but still seriously lacking.


> tell browser vendors to fix their damn engines

Parsing performance of the type they're talking about is an algorithmic fact, not an implementation problem.

Your suggestion is like telling engineers to fix the laws of physics.


SASS parses along those exact nesting rules, so clearly it's possible for the browser to do it as well. Just a question of performance hit at runtime.

In the end having the runtime be fast is likely more important than perfect syntax (as we can still pre-compile via better syntax), but the actual numbers and real world use cases matter a lot.

Are these worst case performance scenarios actually realistic or common? I didn't see anybody speaking to that, but also haven't followed this issue in years. I have seen on a lot of the web standards discussions that many of the contributors will pose theoretical worst case situations as something that should meaningfully impact design of a feature, when those worst case scenarios are extremely rare and unrealistic in practice.


The fact that the article raises the possibility of this limitation being removed in the near future means that it's not a law of physics, only a matter of finding a better algorithm.

Even if it were a law of physics, engineers can often circumvent laws of physics using smart caching and other tricks.

We've been waiting for this feature for decades already. It would have been better if they'd just invested a couple of more years to come up with a better parsing algorithm before standardizing a halfway implementation.


This was a hot topic in discussions and they simply damage control it here for a larger auditory, and in an excellent political way.

The problem is really law of physics-ey. But performance impacts (even naively implemented) were never presented for public evaluation.


> come up with the cleanest, easiest-for-humans syntax as possible, and tell browser vendors to fix their damn engines

W3C has zero leverage over the browser vendors. If they tried to do this the end result would be the same thing that happened to XHTML: the browser vendors would tell them to pound sand and announce that the de facto CSS standard would now be maintained by the WHATWG.


  > come up with the cleanest, easiest-for-humans syntax as possible
I'm definitely on the opposite end of this argument. I really think browsers should be focusing on efficient and theoretically rock-solid foundations. The fact that web standards are slow to evolve and become adopted is a feature, not a bug. If you visit a create-react-app project from 2 years ago you probably couldn't get it running today. I would like a web where a hand-made site from a decade ago still works

The global web standard should be reliable and efficient. Syntactic sugars should be left to the ecosystems and only adopted when they don't confer performance tradeoffs


I agree it's a big mistake to not make the nesting rules compatible to Sass/Less.

> Because of limitations in browser parsing engines, you must make sure the nested selector (.bar in the above example) always starts with a symbol.

How hard can it be.. I know that is always easy to say from the outside but in this case I don't understand why the refuse to implement it. Just labelling it as a performance problem doesn't say much because why should it impact performance to check whether there appears another rule with an opening "{" after it.


Iirc, this requires unbounded lookahead.

Imagine a CPU that is fast but has no concept of stack, so no recursion/callstack for you. You can simulate it through registers, but only as much as register pressure allows in a finite register file. Allowing unbounded call stack requires changing the class of a CPU to the one that has stack (and is slower, due to analogy is incomplete).

In the same way, &-less grammar changes the class of a parser required to parse it. You can’t simply adjust the existing one. In the end it all boils down to the amount of dynamic allocations and backtracking required for parsing the same megabyte of css.

Edit: nothing substantial was said about actual numbers, at least from what I’ve read. It’s a common sense that seems nobody has tested (in this particular case).


The leading "&" should be required.

All of these questions and quandaries only exist because the "&" is optional. If it were simply required, there would be no ambiguity to humans or to parsers.


> Because of limitations in browser parsing engines...

I'm happy about this feature, but they don't really elaborate on what these "limitations" are, except a passing reference later on to "making the parsing engine slower".

Anyone know what the issue is exactly? Why can't they implement it the other way without making the parsing engine slower?


WebKit is on fire lately, awesome.

We only need an autoupdate feature for Safari. Badly. It’s the only not evergreen big browser, to my knowledge.


Another benefit I'm not seeing is that sass/less/minifiers can now target this new native nesting for the output, which would reduce the overall byte size of the output.

So you don't need to use nesting in your code if you don't want to, but can still take advantage for smaller minified css files using a transpiler.


This syntax matches the CSS Working Group's recommendations, is that correct?

> "starting the nested selector with an identifier is invalid"

https://www.w3.org/TR/css-nesting-1/#example-34e8e94f


I'm losing track of what CSS can do.

Do we have inheritance already?

Pseudocode of what I mean:

    .info {
        font-size: 8px;
    }

    .news extends .info {
        color: black;
    }
So news are displayed in an 8px black font.


nope. you've got a couple of options -

  .info {
   font-size: 8px;
  }
  
  .news {
   color: black;
  }
  
  <div class="info  news">asdf</div>
or maybe

  .info {
   font-size: 8px;
  }
  
  .news {
   color: black;
  }
  
  <div class="news"><p class="info">asdf</p></div>
or even

  .info, .news {
   font-size: 8px;
  }
  
  .news {
   color: black;
  }
  
  <div class="news">asdf</div>
but you've got to use LESS/SCSS for true 'extends' type functionality. vanilla CSS is more focused on inheritance.


Out of these, only the last one seems somewhat okish to me. But it would be annoying to add another selector everytime you add a class that uses the rule.

If that is all we have, then I will just stick to css variables:

    :root {
      --info-font-size: 8px;
    }

    .info {
      font-size: var(--info-font-size);
      color: grey;
    }

    .news {
      font-size: var(--info-font-size);
      color: black;
    }


This half assed version of nesting is lame, as are all the others. Just give us SCSS its been ten years now, pave the cowpath.


What's the difference between this and SCSS nesting? It seems pretty full-featured to me. What's missing?


Yeah... the only difference _in terms of nesting_ that I'm aware of is exactly as discussed in the blog post: you must start a nested section with a symbol.

Sass itself has a huge amount of features... is the expectation that we should just adopt a Sass implementation into the browser or something?


The other difference is that SCSS nesting can also be used for string concatenation, as in BEM classes. Such as:

  .some-class {
      color: red;
      &__child {
          color: blue;
      }
  }
Which compiles to

  .some-class {
      color: red;
  }
  .some-class__child {
      color: blue;
  }


Oh right I kinda hate that and feel like it leads to strangely named classes


    dialog {
      background-color: white;
      color: black;
      input {
        width: 200px;
      }
    }
Doesn't work.


Put it in my veins!!!! Finally!


I wonder if any editor (vscode or plugin) support nested search soon...


What would this mean for the type of website designs we could see?


Css is one hell of a spaghetti mess, why need nested css?


Better late than never :)

Very happy to see something major like this being adopted.


"Everyone wishes CSS nesting could use the same kind of simple syntax that Sass does. That’s impossible"

Oh man... let the asteroid come.


This is a good thing.

I'm currently writing a toy "javascript" bundler. I implemented a CSS parser in the past (mostly for linting) and it took me a few hours. Trying to do the same with SCSS made me give up halfway. The test suite was >6000 tests or so and I got up to about 3000 or something, but it gets harder the further up you go. There's lots of other people in Github that are smarter than me and had the same experience, leaving their parser halfway finished. There's a lot of smart stuff in SCSS, and that is perfectly fine for a compile-time tool, but it's not something that's fast enough for a browser, or simple enough that can be added quickly to their current parsers.


So they dropped "@nest"?


Yes @nest is gone


Couldn’t `this` just be a reserved keyword instead of `&`? All these symbols, CSS has become so Perly.


Couldn't <this> be a custom HTML element? So there'd be a naming clash.


option 3 really was the best option


It's great it's here, but isn't everyone and their dog who wants features like this using PostCSS, LESS or SASS? In a build environment that nearly makes this transparent.

I use Vite and PostCSS and a bevy of linters, image processing tools, even for CSS-only projects because they're so fast and generally so good at what they do that it'd be silly not to. I used to hodge tools together with Makefiles but Vite in particular has made the setup for all this stupid-simple.

I make changes, 100ms later Vite deposits a new, optimised build into my Django static dir.


This has benefits even if you use those pre-processors. One I have in mind is smaller CSS file sizes.


I can think of a very few, very extreme examples that I've worked on where that might be a registrable amount, but even then, you're only saving on duplicated parent classes/element which would have been taken care of by simple gzip compression.

There are [increasingly few] times when it's just nice to just write CSS and I guess unifying nesting will make that nicer, but I don't think there are tangible benefits over "flat" production output.


[flagged]


Can you support saying why it's an anti-pattern rather than just saying something inflammatory?




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: