From 81458c06965d158ff870b3a50eec3eda93b5bfa2 Mon Sep 17 00:00:00 2001 From: OfirHaf Date: Sun, 10 May 2026 08:06:56 +0300 Subject: [PATCH 1/4] fix: strip trailing semicolons from style directive values before setProperty When a reactive style directive value contains a trailing semicolon (e.g. `style:background={`conic-gradient(...);'`}`), the initial render works because it goes through cssText which tolerates semicolons, but subsequent reactive updates call el.style.setProperty() which silently rejects values containing semicolons, leaving the style unchanged. Strip trailing semicolons from the value in update_styles before calling setProperty, making reactive updates consistent with the initial render. Fixes #18182 --- packages/svelte/src/internal/client/dom/elements/style.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/svelte/src/internal/client/dom/elements/style.js b/packages/svelte/src/internal/client/dom/elements/style.js index 3e05eec30e..8fde5e1fea 100644 --- a/packages/svelte/src/internal/client/dom/elements/style.js +++ b/packages/svelte/src/internal/client/dom/elements/style.js @@ -15,7 +15,10 @@ function update_styles(dom, prev = {}, next, priority) { if (next[key] == null) { dom.style.removeProperty(key); } else { - dom.style.setProperty(key, value, priority); + // setProperty rejects values with trailing semicolons; strip them so that + // reactive updates behave consistently with the initial cssText assignment + var str_value = String(value).replace(/;+\s*$/, ''); + dom.style.setProperty(key, str_value, priority); } } } From 5d8fa9df7a9fe88c14d703b7d2e2cb3e30ec05ee Mon Sep 17 00:00:00 2001 From: OfirHaf Date: Sun, 10 May 2026 09:51:07 +0300 Subject: [PATCH 2/4] fix: use local value variable instead of next[key] in null check Applies reviewer suggestion for consistency since value is already assigned from next[key] on the line above. Also adds required changeset for patch version bump. --- .changeset/cuddly-cougars-grow.md | 5 +++++ packages/svelte/src/internal/client/dom/elements/style.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/cuddly-cougars-grow.md diff --git a/.changeset/cuddly-cougars-grow.md b/.changeset/cuddly-cougars-grow.md new file mode 100644 index 0000000000..a319be9775 --- /dev/null +++ b/.changeset/cuddly-cougars-grow.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: strip trailing semicolons in style directive reactive updates diff --git a/packages/svelte/src/internal/client/dom/elements/style.js b/packages/svelte/src/internal/client/dom/elements/style.js index 8fde5e1fea..5a84604d09 100644 --- a/packages/svelte/src/internal/client/dom/elements/style.js +++ b/packages/svelte/src/internal/client/dom/elements/style.js @@ -12,7 +12,7 @@ function update_styles(dom, prev = {}, next, priority) { var value = next[key]; if (prev[key] !== value) { - if (next[key] == null) { + if (value == null) { dom.style.removeProperty(key); } else { // setProperty rejects values with trailing semicolons; strip them so that From 41550a51150c67bf9923626ab4af4321166532b7 Mon Sep 17 00:00:00 2001 From: OfirHaf Date: Sun, 10 May 2026 11:57:47 +0300 Subject: [PATCH 3/4] test: add runtime-browser regression test for style directive trailing semicolon --- .../_config.js | 21 +++++++++++++++++++ .../main.svelte | 5 +++++ 2 files changed, 26 insertions(+) create mode 100644 packages/svelte/tests/runtime-browser/samples/style-directive-trailing-semicolon/_config.js create mode 100644 packages/svelte/tests/runtime-browser/samples/style-directive-trailing-semicolon/main.svelte diff --git a/packages/svelte/tests/runtime-browser/samples/style-directive-trailing-semicolon/_config.js b/packages/svelte/tests/runtime-browser/samples/style-directive-trailing-semicolon/_config.js new file mode 100644 index 0000000000..1e96ec17f7 --- /dev/null +++ b/packages/svelte/tests/runtime-browser/samples/style-directive-trailing-semicolon/_config.js @@ -0,0 +1,21 @@ +import { assert_ok, test } from '../../assert'; + +export default test({ + html: `
`, + + test({ assert, target, window, component }) { + const div = target.querySelector('div'); + assert_ok(div); + + // Initial value with trailing semicolon — should produce valid CSS + assert.equal(window.getComputedStyle(div).color, 'rgb(255, 0, 0)'); + + // Update to a new value that also has a trailing semicolon + component.color = 'blue;'; + assert.equal(window.getComputedStyle(div).color, 'rgb(0, 0, 255)'); + + // Update to a value without trailing semicolon — should still work + component.color = 'green'; + assert.equal(window.getComputedStyle(div).color, 'rgb(0, 128, 0)'); + } +}); diff --git a/packages/svelte/tests/runtime-browser/samples/style-directive-trailing-semicolon/main.svelte b/packages/svelte/tests/runtime-browser/samples/style-directive-trailing-semicolon/main.svelte new file mode 100644 index 0000000000..3ba2e22bc0 --- /dev/null +++ b/packages/svelte/tests/runtime-browser/samples/style-directive-trailing-semicolon/main.svelte @@ -0,0 +1,5 @@ + + +
From e86e2c7cd501984e242e95d5ab41c95de9b8e0ad Mon Sep 17 00:00:00 2001 From: OfirHaf Date: Fri, 15 May 2026 10:56:01 +0300 Subject: [PATCH 4/4] fix: add DEV warning for style directive values with trailing semicolons --- .../src/internal/client/dom/elements/style.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/svelte/src/internal/client/dom/elements/style.js b/packages/svelte/src/internal/client/dom/elements/style.js index 5a84604d09..6c00103607 100644 --- a/packages/svelte/src/internal/client/dom/elements/style.js +++ b/packages/svelte/src/internal/client/dom/elements/style.js @@ -1,3 +1,4 @@ +import { DEV } from 'esm-env'; import { to_style } from '../../../shared/attributes.js'; import { hydrating } from '../hydration.js'; @@ -15,10 +16,18 @@ function update_styles(dom, prev = {}, next, priority) { if (value == null) { dom.style.removeProperty(key); } else { + var str_value = String(value); + + if (DEV && /;+\s*$/.test(str_value)) { + // eslint-disable-next-line no-console + console.warn( + `[svelte] Style directive value for "${key}" has a trailing semicolon which is invalid and will be removed. Remove the trailing ";" from the value.` + ); + } + // setProperty rejects values with trailing semicolons; strip them so that // reactive updates behave consistently with the initial cssText assignment - var str_value = String(value).replace(/;+\s*$/, ''); - dom.style.setProperty(key, str_value, priority); + dom.style.setProperty(key, str_value.replace(/;+\s*$/, ''), priority); } } }