Reading and Writing Styles
Set inline styles on page elements and read computed styles from C++.
On this page
You can style page elements directly from C++ by setting inline styles and reading computed styles. Writing inline styles is fast enough to run every frame— native code can update animations and interface elements directly.
To measure an element or scroll its contents, see Element Geometry and Scrolling.
Setting Styles
Once you find an element (see Finding and Modifying Elements), set inline styles by assigning directly to members of its style property. Values parse the same as in JavaScript— anything that doesn't parse is ignored and the old value stays:
panel.style.display = "none";
panel.style.border = "1px solid white";
Numbers and Units
Use helpers like dom::StyleValue::Px() and Pct() for computed values without string formatting (plain numbers work for unitless properties like opacity). Number literals like "50%" are checked when you compile— a typo like "50pxx" won't compile.
bar.style.width = dom::StyleValue::Pct(health * 100);
bar.style.opacity = 0.8;
🚧 Properties Ignore Unsupported Units
Assigning a number that a property doesn't accept has no effect— the previous value stays (such as setting a unitless
5onwidthor a pixel value onopacity). Use a unit the property expects, likedom::StyleValue::Px(5). When DOM diagnostics are on, the library logs a warning for each ignored write.
Colors
Pass Color(r, g, b, a) for colors from your data (channels range from 0 to 1, and alpha defaults to 1). Wrapping a hex or rgb() literal in Color("...") checks it when you compile (unlike a bare string), while named colors and runtime text use Color::Parse() (see Working with Colors).
bar.style.backgroundColor = Color(1.0f, 0.2f, 0.2f, 0.8f);
bar.style.color = Color("#ff3366");
Colors from Text
Call Color::Parse() to read CSS color text at run time (eg, from a theme file or a user setting). It accepts any CSS color format (including named colors and hsl()), and returns an invalid Color if the text didn't parse, so you can check it first.
Color accent = Color::Parse(settings.accent);
if (accent)
hud.style.color = accent;
Custom Properties
You can set a custom property (--name) by indexing style with its property name. Descendant elements inherit the assigned value (text or a Color). Pass numbers as text like "8px" since dom::StyleValue does nothing on a custom property.
hud.style["--accent"] = Color(0.2f, 0.8f, 1.0f);
hud.style["--radius"] = "8px";
Theming the Whole Page
To theme the whole page, set a custom property on the root element. Every rule that uses it (var(--accent)) updates.
document.documentElement().style["--accent"] = Color(0.2f, 0.8f, 1.0f);
Names in Strings
You can set any property by name in a string using either its CSS name (background-color) or its JavaScript name (backgroundColor). When you know the name as you write the code, use the member instead (hud.style.backgroundColor) since the compiler checks it.
for (const auto& [name, value] : theme)
hud.style[name] = value;
cssText reads or replaces the whole inline declaration (as on the web).
Marking a Value !important
Pass true as the third argument to setProperty() to mark a value !important. Like the web, setProperty() takes the CSS name only ("background-color", not "backgroundColor"):
hud.style.setProperty("background-color", "navy", true);
Removing Properties
Calling removeProperty() removes a property and returns its old value (CSS name only, like the web). You can also remove the property by assigning an empty string, an empty dom::StyleValue(), or an unset Color (eg, a value copied from an element that had none):
std::string old = hud.style.removeProperty("background-color");
bar.style.width = "";
Reading Styles
Reading an el.style member returns only the value set inline (it reads as empty when a stylesheet sets it). Call dom::getComputedStyle(el) to inspect the style that applies— it has the same named members as JavaScript's getComputedStyle(el):
auto computed = dom::getComputedStyle(bar);
std::string width = computed.width;
🚧 Reads Can Trigger Layout
Reading a computed style applies pending style changes first. Any property that depends on layout (eg,
width,margin, ortop) also runs a layout pass— make all changes first and then read. Measuring an element follows the same rule (see Element Geometry and Scrolling).
Reading Numbers and Colors
Computed properties return text like "300px" or "rgb(255, 51, 119)", just like JavaScript. Call AsStyleValue() to parse a number with a unit (lengths return in pixels), or AsColor() to parse a Color. A property that isn't set returns an empty value, and a value that isn't a single number or color (like auto) returns an invalid one— both evaluate to false so you can check the result before using it:
if (dom::StyleValue width = computed.width.AsStyleValue())
PlaceMinimap(width.value);
Color accent = computed.color.AsColor();
Keeping a Computed Style
A computed style is live— each read sees the element's current styles. You can get it once and read it whenever you need (eg, every frame).
dom::ComputedStyle computed = dom::getComputedStyle(hud);
// Later: sees the current styles.
std::string opacity = computed.opacity;