> 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
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.
Personally I do agree and I like the explicitness of always having the &
Possibly mixins, loops, and variables, which, unlike CSS variables, can be used in media queries.
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.
Because there was no “none of the above” option, which developers asked for.
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 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.(We discussed adopting Sass's behavior in <https://github.com/w3c/csswg-drafts/issues/8310#issuecomment...> but ultimately dropped it.)
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)
Syntactic sugar, sometimes, is the promise of sunnier mornings and that matters.
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.
They're tracking work in https://bugzilla.mozilla.org/show_bug.cgi?id=1648037
.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.
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.
So it's the latest chrome, Safari technical preview, and edge behind a flag. No disposition from Firefox yet afaict.
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.
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.
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)
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.
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.
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.]
: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.
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.
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?
We only need an autoupdate feature for Safari. Badly. It’s the only not evergreen big browser, to my knowledge.
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.
> "starting the nested selector with an identifier is invalid"
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.Very happy to see something major like this being adopted.
Oh man... let the asteroid come.
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.