From b6b6d0386901cac3dd0f927b438b4a4359840df9 Mon Sep 17 00:00:00 2001
From: Mathias Picker <48158184+MathiasWP@users.noreply.github.com>
Date: Tue, 5 May 2026 13:52:23 +0200
Subject: [PATCH] fix: drop style attribute when value normalises to empty
Previously the client kept an empty `style=""` for empty-string values
while SSR dropped the attribute, which is a hydration mismatch and now
also affects every object/array input that filters down to nothing
(`style={false}`, `style={{}}`, `style={[null, false]}`). Coerce empty
to `null` in `to_style` so client and SSR agree, matching what the
directive path already did and what `to_class` does for `class={''}`.
Two existing tests asserted `
` for `component.style = ''`
as an incidental side effect; updated to expect the attribute dropped.
---
packages/svelte/src/internal/shared/attributes.js | 4 +++-
.../samples/async-fork-attributes/_config.js | 8 ++++----
.../runtime-runes/samples/style-update/_config.js | 10 ++++++----
3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/packages/svelte/src/internal/shared/attributes.js b/packages/svelte/src/internal/shared/attributes.js
index 99a0b13d92..cb45af1839 100644
--- a/packages/svelte/src/internal/shared/attributes.js
+++ b/packages/svelte/src/internal/shared/attributes.js
@@ -261,5 +261,7 @@ export function to_style(value, styles) {
return new_style === '' ? null : new_style;
}
- return value == null ? null : String(value);
+ // Empty results drop the attribute entirely so that client and SSR agree
+ // (the directive path above already returns `null` for empty output).
+ return value == null || value === '' ? null : String(value);
}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-fork-attributes/_config.js b/packages/svelte/tests/runtime-runes/samples/async-fork-attributes/_config.js
index 59bcdeb7f5..7c64866995 100644
--- a/packages/svelte/tests/runtime-runes/samples/async-fork-attributes/_config.js
+++ b/packages/svelte/tests/runtime-runes/samples/async-fork-attributes/_config.js
@@ -12,8 +12,8 @@ export default test({
`
-
foo
-
foo
+
foo
+
foo
foo
`
);
@@ -51,8 +51,8 @@ export default test({
`
-
foo
-
foo
+
foo
+
foo
foo
`
);
diff --git a/packages/svelte/tests/runtime-runes/samples/style-update/_config.js b/packages/svelte/tests/runtime-runes/samples/style-update/_config.js
index 52690a431a..347ed46c36 100644
--- a/packages/svelte/tests/runtime-runes/samples/style-update/_config.js
+++ b/packages/svelte/tests/runtime-runes/samples/style-update/_config.js
@@ -37,14 +37,16 @@ export default test({
component.style = '';
flushSync();
+ // empty results drop the attribute on both client and SSR (was previously
+ // `` on the client only — a hydration mismatch)
assert.htmlEqual(
target.innerHTML,
`
-
-
+
+
-
-
+
+
`
);