-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Native CSS Nesting #8587
Comments
Pretty sure you need p {
& strong {
line-height: 1.2;
}
} The other is invalid. I think a good rule of thumb is every must start with a symbol. |
I think there is still an issue. According to this Chrome article the following should work but in Svelte it doesn't: <script>
let name = 'world';
</script>
<div class="card">
<h1>Hello {name}!</h1>
</div>
<style>
.card {
:is(h1) {
color: red;
}
}
</style> It does however work with the additional ampersand .card {
& :is(h1) {
color: red;
}
} So my guess is that it is currently intentionally always expecting the |
Ya, I was wrong on the first example (it always requires either a starting symbol like an |
It doesn't work without an ampersand. I tried it in a REPL and in SvelteKit. From what I understand the CSS parser that Svelte uses doesn't support optional ampersands and potentially other features yet, see: csstree/csstree#186 (comment) |
I found another potential issue. The following styles: <style>
div {
& :global(*) {
color: yellow;
}
}
div :global(*) {
color: red;
}
</style> produce the following output: <style>
div.svelte-ofba00 {
& :global(*) {
color: yellow;
}
}
div.svelte-ofba00 * {
color: red;
}
</style> which means either Edit: Actually, it looks like nested rules aren't scoped at all and are global by default https://svelte.dev/repl/783f0b40b80140efbcf486d29a9c41a4?version=3.59.1 |
Hi, I would like to highlight a bug created due to the lack of support of native CSS nesting. See the REPL. As code in nested selectors is not processed, and thus output as is, Minimal input: <style>
@keyframes dialog-background-light {
to { background: oklch(1 0 0 / .3); }
}
dialog::backdrop {
/* works as intended: animation is renamed with a hashed ID */
animation: dialog-background-light .5s ease-out forwards;
}
dialog {
&::backdrop {
/* animation is not renamed */
animation: dialog-background-light .5s ease-out forwards;
}
}
</style> Output (beautified): @keyframes svelte-1ci0amd-dialog-background-light {
to {
background: oklch(1 0 0 / 0.3);
}
}
dialog.svelte-1ci0amd::backdrop {
animation: svelte-1ci0amd-dialog-background-light 0.5s ease-out forwards;
}
dialog.svelte-1ci0amd {
&::backdrop {
/* animation is not renamed */
animation: dialog-background-light 0.5s ease-out forwards;
}
} As you can see, the non-nested |
Nested media rules are not working correctly. These two examples should be equivalent but only the last one works. a {
&::after {
@media (prefers-reduced-motion: reduce) {
opacity: 0;
transition: opacity var(--nav-transition-time) ease-in-out;
}
}
} a {
@media (prefers-reduced-motion: reduce) {
&::after {
opacity: 0;
transition: opacity var(--nav-transition-time) ease-in-out;
}
}
} |
Can we support: :global {
.foo {
/*...*/
}
} Like we do in preprocessors? |
I think that's not the case anymore. |
That's correct however there are some complexities in supporting it and currently only the most recent version of some browsers supports it due to the complexities of distinguishing between a CSS declaration property and CSS rule I am currently working on implementing CSS nesting for Svelte and will probably opt to require the |
I have created a PR that |
I'm sure it's more complex to parse, but now every browser, except Edge (which will have it soon since it's Chromium based) and Opera support nesting of element selectors without ampersand. So it would be really great if we could get support for this soon :) |
Excluding CSS type element selectors closes sveltejs#9320 closes sveltejs#8587
closes sveltejs#8587
@enyo @jrmoynihan I've fully implemented support for CSS nesting in #9549, including support for type (element) selectors, combinator prefixes and |
Is this closed by #10491 ? |
It’s released in 5.0.0-next.57, but apparently the REPL (wanted to test my issue) is not compatible with v5 yet. |
I haven't seen any code samples posted above mention that .child {
.parent & {
color: red;
}
} Is equivalent to: .parent .child {
color: red;
} Mentioning this since I saw comments say "the & always goes at the start" which isn't true. I want to make sure that the fix does support this use case. |
@Dan503 It looks like that was included in the pull request #9549 (comment) which was merged in this pr #10491 (comment) |
I'm not sure about the PR that @Rich-Harris implemented, but I assume he added that support too. My PR did have code to handle that |
Nested CSS support was added to Svelte 5 (it's not practical to backport it to 4) so I'll close this |
Describe the problem
Native CSS Nesting without a pre-processor is stable since Chromium 112 (March 2023), and is in technical preview of Safari 16.5.
However, this syntax is not supported by Svelte's processor in
<style>
tags. Especially in instances like using Svelte in third-party web containers where you might not have control over the availability of additional pre-processors, this makes writing the style rules far simpler/easier than using complex selectors or a multitude of classes, allowing more rapid and readable prototyping.Surprisingly, there's no open or closed issue covering this topic.
Sources:
https://caniuse.com/css-nesting
https://web.dev/web-platform-04-2023/
https://developer.chrome.com/articles/css-nesting/
https://webkit.org/blog/13813/try-css-nesting-today-in-safari-technology-preview/
Describe the proposed solution
Treat nested selectors as valid syntax. Given this html:
All of these syntaxes should work without error:
Alternatives considered
Using a pre-processor is the alternative, but it adds unnecessary bloat to the DX.
Importance
nice to have
The text was updated successfully, but these errors were encountered: