svelte icon indicating copy to clipboard operation
svelte copied to clipboard

scoping class is incorrectly added to element

Open Florinstruct opened this issue 2 years ago • 3 comments

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

Florinstruct avatar Nov 01 '22 18:11 Florinstruct

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) {

Rich-Harris avatar Nov 01 '22 20:11 Rich-Harris

Workaround is perfectly fine for me right now. Thanks, Rich!

Florinstruct avatar Nov 02 '22 16:11 Florinstruct

There is definitely something up with css scoping. See #7991

subpx avatar Dec 07 '22 21:12 subpx