svelte
svelte copied to clipboard
scoping class is incorrectly added to element
Describe the bug
Unlike npm run dev
(gonna call it "dev" from now on), npm run build
(call it "build") does not seem to generate all HTML classes required for styling.
When comparing the markup generated, build does omit many classes - probably because it has other rules for checking if a class is needed than dev? Anyway: in most cases that seems to be okay. In some, it leads to broken styles.
Reproduction
A simple table with some CSS:
<table>
<thead>
<tr>
<th>Head 1</th>
<th>Head 2</th>
<th>Head 3</th>
</tr>
</thead>
<tbody>
<tr>
<th>Field 1</th>
<td>Field 2</td>
<td>Field 3</td>
</tr>
<tr>
<th>Field 1</th>
<td>Field 2</td>
<td>Field 3</td>
</tr>
</tbody>
</table>
<style>
tbody tr:hover th,
tbody tr:hover td {
background-color: red;
}
</style>
Note that the table body contains both th
and td
.
npm run dev
Dev adds a class to the tr
, but only adds it to one of the child elements: th
. This looks fine, but is already inconsistent. Screenshot
npm run build
Build does not add a class to the tr
and shows the same inconsistent behaviour with the child elements. The missing class makes this look broken: on hover, the first cell (th
) does not change background. Screenshot
npm run build without thead
Removing the thead
from the table, npm run build
, will leave out generated classes from both the HTML and CSS. This looks fine and is probably what the compiler output should be. Screenshot
(I would have linked Stackblitz but this bug applies to npm run build
only and not yarn dev
. Sorry, if there's a way to simulate this online and I missed it.)
Logs
No response
System Info
System:
OS: Windows 10 10.0.22000
CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Memory: 7.93 GB / 15.71 GB
Binaries:
Node: 16.17.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.15 - ~\AppData\Roaming\npm\yarn.CMD
npm: 8.18.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Spartan (44.22000.120.0), Chromium (106.0.1370.37)
Internet Explorer: 11.0.22000.120
npmPackages:
@sveltejs/adapter-auto: next => 1.0.0-next.86
@sveltejs/kit: next => 1.0.0-next.531
svelte: ^3.50.1 => 3.52.0
vite: ^3.2.0 => 3.2.2
Severity
serious, but I can work around it
Additional Information
No response
This is a bug in Svelte rather than SvelteKit — it's visible in this reproduction: https://svelte.dev/repl/e14ddc6557ac4352b86fbbe574bcc843?version=3.52.0
The scoping class shouldn't be added to the <tr>
elements or the corresponding tr:hover
selectors — we only need to add the scoping class to the outer elements. Adding the class to the tr
is superfluous. Yet for some reason, that's what's happening here, but only in the case of the th
block — the selector is (incorrectly) being scoped (tr.svelte-xyz123:hover
) but the class (correctly) isn't being added to the element.
It's very weird that it's working differently for the th
and the td
. Doesn't seem to matter if they're separate declarations or comma-separated selectors, or what order they appear in. Have no idea what could be causing that. Am also at a loss as to why it's working as you expect in dev.
Until we get to the bottom of this, there's a workaround:
-tbody tr:hover th {
+tbody tr:hover :is(th) {
Workaround is perfectly fine for me right now. Thanks, Rich!
There is definitely something up with css scoping. See #7991