Skip to content

Themes and CSS

In x4js, appearance is not decided in code: it lives in CSS. Each component brings its structure and its behaviour, and the stylesheet does the rest.

Each component carries a class named after it, and those of its base classes.

Component Classes carried by the element
Button x4button
VBox x4vbox, x4box
MainView, which extends VBox mainview, x4vbox, x4box

So you target a component, provided or your own, without declaring anything. The cls property adds your own classes when two elements of the same type must be told apart.

.mainview {
padding: 12px;
gap: 8px;
.x4button {
min-width: 90px;
}
}

Colors are not hard-coded in the components. They go through CSS variables, organised in three levels:

Level Examples Role
Primary scale --color-primary-a5 … --color-primary-a90 The shades of the base color.
Meaning variables --accent-background, --border, --text-primary, --background-primary What a color means in the interface.
Component variables --button-background, --listbox-border, --chart-color-1 The fine tuning of one component.

Each level builds on the previous one. Depending on what you want to change, act at the right level.

Redefine the primary scale, once per theme. All components follow.

:root {
--color-primary-a40: #3d8fbd;
--color-primary-a50: #126e9e;
--color-primary-a60: #0e5a80;
// … the other shades of the scale
}
:root {
--border: #cfdae0;
--accent-background: #126e9e;
}
.x4button {
--button-background: #002a40;
--button-color: white;
}

The list of the variables of each component is in the API reference, on the page of its class.

A theme is a set of values for these variables. To offer several, redefine them under a selector of your choice, and switch that selector.

:root {
--background-primary: #fbfdfe;
--text-primary: #002a40;
}
:root.dark {
--background-primary: #002a40;
--text-primary: #f0f9fd;
}

There is no “theme” object to handle in TypeScript: do not create one to duplicate what CSS already does.

Sometimes a value depends on data: a color picked by the user, a computed width. A component can then read or write a CSS variable.

panel.setStyleVariable( "--panel-accent", color );
const height = panel.getStyleVariable( "--row-height" );
  1. No cosmetics in code. Colors, margins and fonts go in the stylesheet.
  2. No fighting with CSS. If you need negative margins or !important, look for the mistake in the CSS.
  3. CSS dresses, it does not remove a behaviour. To remove the close button of a dialog, configure the component through its properties (closable: false), do not hide it in CSS.