DioxusLabs / DioxusLabs/dioxus

Style updates with a var() in a CSS shorthand are silently reverted

Open
#5,739 0 comments 0 reactions 0 assignees View on GitHub
bug
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.