DioxusLabs / DioxusLabs/dioxus
Style updates with a var() in a CSS shorthand are silently reverted
- Dominant language
- Rust
- Stars
- 39.1k
- Forks
- 1.9k
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 4
Description
👋🏻
**Problem**
Updating a `style` attribute where a CSS shorthand (e.g. `background`) takes a `var()` value is silently reverted by the web interpreter. Initial mount and literal values work; only updates from a literal to a `var()` value are affected.
Cause: `setAttributeInner`'s `case "style"` (from #3950) snapshots existing inline properties, sets the new attribute, then restores every property the new style "does not define" (`if (!node.style.getPropertyValue(prop))`). Per css-variables-1 §3.2, the longhands of a shorthand containing `var()` hold a pending-substitution value and serialize as `""`, so the restore loop re-applies the old longhands on top of the new value.
Related: #4389 (sibling regression of the same loop); the Rust-side merge in #4510 would remove the loop and should fix this too.
Workaround: use the longhand (`background-color: var(--x)`).
**Steps To Reproduce**
- `dx serve` this app (web):
```rust
use dioxus::prelude::*;
fn main() { dioxus::launch(app); }
fn app() -> Element {
let mut on = use_signal(|| false);
let color = if on() { "var(--accent)" } else { "transparent" };
rsx! {
div { style: "--accent: crimson;",
button { onclick: move |_| on.toggle(), "Toggle" }
span { style: "display:inline-block;width:20px;height:20px;background:{color}" }
}
}
}
```
- Click "Toggle".
**Expected behavior**
The square turns crimson. Actual: it stays transparent forever (a MutationObserver shows
the new `background:var(--accent)` landing, then ~9 `setProperty` calls restori
longhands). Using `background-color:{color}` or a literal color works.
**Environment:**
- Dioxus version: 0.7.9 and 0.7.10
- Rust version: 1.97.1
- OS info: Linux
- App platform: web
Contributor guide
No contributing guide indexed for this repository
Research direction
Search the web interpreter for setAttributeInner and its case "style" handling, then compare the behavior with the Rust-side merge described in #4510. Run the supplied dx serve reproduction and inspect the style updates when toggling. Done means changing from the literal color to background:var(--accent) turns the square crimson without restoring the old longhand values.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, rust
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100