-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Description
Describe the problem
Svelte's CSS scoping is great and allow to avoids a lot of mistakes/conflicts.
But it is logically limited to the class
attribute and the class:
directive.
Obviously the CSS compiler can't detect classes defined outside of these attribute/directive...
It cannot detect:
- The classes set inside an use:action.
- The classes set via the DOM (for ex. via an external library).
And in this case, we got the famous warning "Unused CSS selector" :
<div class="btn" use:anActionThatCanAddClasses>
...
</div>
<style>
.btn {
background: blue;
}
/* WARNING : Unused CSS selector */
.important {
background: red;
border: 3px solid black;
}
</style>
The actual solution is to use the :global(...)
modifier, but if it's misused it can break the scoping and have non-intuitive behavior on the selector specificity.
Example :
.btn {
background: blue;
}
/* NO warning, but
- style is not scoped, and can affect other nodes
- some properties are not applied, as the class ".important"
is less relevant than the ".btn.svelte-XXXX" scoped CSS.
*/
:global(.important) {
background: red; /* NOT applied */
border: 3px solid black;
}
The correct way to do this is to bundle the scoped and global CSS , like this :
.btn:global(.important) {
...
}
But it's verbose and not intuitive.
Describe the proposed solution
It should be possible to declare classes that "could" be added to a node.
This would only serve the CSS compiler and would have no impact on the generated JavaScript code.
I think we could give a special meaning to the use:class="names"
directive.
It's a non-breaking change as class
is a keyword, and so it cannot be used as an action.
So use:class="names"
could be a special case, which would expect a string containing the class names (like a normal class
attribute).
Ex:
<div class="btn" use:class="important"> ... </div>
Which means that this <div>
only has the "btn" class, but it can have the "important" class.
The CSS compiler would use this in addition to the class attribute/directive to determine the scope of CSS rules, which will avoids the need of :global
.
Example :
<div class="btn" use:class="important" use:anActionThatCanAddClasses>
...
</div>
<style>
.btn {
background: blue;
}
/* It just work ! */
.important {
background: red;
border: 3px solid black;
}
</style>
Alternatives considered
continue to use :global()
Importance
nice to have