Skip to content
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

Svelte 5: Bug: style: directives are overwritten by style attribute in certain conditions (same for class:) #13531

Closed
pepkin88 opened this issue Oct 8, 2024 · 1 comment

Comments

@pepkin88
Copy link

pepkin88 commented Oct 8, 2024

Describe the bug

Under certain conditions, style: directives get overwritten by the style attribute, instead of being merged.
In Svelte 4 they were always merged.
In Svelte 5 the style attribute is set first, then style: directives are applied onto it (from my observation). However, sometimes the order is incorrect and style: directives get overwritten by the style attribute.

The same issue applies to class: directives.

Reproduction

<script>
	let array = $state([{ a: 0, b: 0 }])
</script>

<div>
	Change:
	<button type="button" onclick={() => array[0].a++}>`a`</button>
	<button type="button" onclick={() => array[0].b++}>`b`</button>
</div>

<div>
	{#each array as item (item.a)}
		<div style="z-index: {Number(item.b)};" style:background-color="#080">
			{#if true}
				it should stay green (a: {item.a}; b: {item.b})
			{/if}
		</div>
	{/each}
</div>

<div>
	<div style="z-index: {Number(array[0].b)};" style:background-color="#080">
		{#if true}
			it should stay green (a: {array[0].a}; b: {array[0].b})
		{/if}
	</div>
</div>

Link to REPL

This is the most minimal example I could make. It was spotted in a real project, while trying to migrate to Svelte 5.

Try pressing buttons in that order:

  1. `a`
  2. `b`
  3. `a`

You will notice that:

  1. after first click on `a` everything works as expected
  2. after first click on `b` the green background disappears
  3. after second click on `a` the green background reappears only in the first block

However, they should always stay green.

Similar issue affects class: directives, as this REPL shows.


In Svelte 4 I can see in the compiled code that the merging is done with the set_style function:

// ...

set_style(div, "z-index", Number(/*item*/ ctx[3].b));

// ...

set_style(div, "background-color", `#080`);

// ...

But in Svelte 5 only style: directives are trying to merge, the style attribute is set directly:

// ...

$.template_effect(() => $.set_attribute(div_2, "style", `z-index: ${Number($.get(item).b) ?? ""};`));

// ...

$.template_effect(() => $.set_style(div_2, "background-color", "#080", undefined, true));

// ...

I believe it should merge the same way as in Svelte 4. That way, even if those effects were applied in a different order, at least different properties wouldn't overwrite. Although probably the calling order also should be fixed.

Logs

No response

System Info

System:
    OS: macOS 14.5
    CPU: (10) arm64 Apple M1 Pro
    Memory: 150.59 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.17.0 - /usr/local/bin/node
    npm: 10.8.2 - /usr/local/bin/npm
    pnpm: 8.9.0 - /usr/local/bin/pnpm
    bun: 1.0.14 - ~/.bun/bin/bun
  Browsers:
    Chrome: 129.0.6668.90
    Chrome Canary: 131.0.6764.0
    Safari: 17.5
    Safari Technology Preview: 18.0

(using Vivaldi 6.9, not detected by the script)



### Severity

annoyance
@Conduitry
Copy link
Member

Duplicate of #13270.

@Conduitry Conduitry closed this as not planned Won't fix, can't repro, duplicate, stale Oct 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants