CSS Custom Properties and Variables

CSS custom properties and variables allow you to define custom properties and their values, which you can then later reference in other style sheets, or in JavaScript. They reduce copy-paste, ensure consistency, and make it easier to read and understand style sheets.

The built-in themes in Vaadin and their customizability are based on custom properties.

Custom properties are different from traditional CSS-preprocessor (Sass, Less, Stylus, etc.) variables. They do not need to be compiled before sending them to the browser and they are capable of changing their value at runtime, even based on the DOM hierarchy. You can also use them from JavaScript.

Caution
CSS custom properties are not natively supported in Internet Explorer 11. A polyfill is automatically loaded which makes it possible to use them, but with some limitations.

Defining Custom Properties

The most common place to define custom properties is at the document root, the <html> element. Custom properties can be defined inside any CSS selector, scoping them to that particular selector.

Custom properties need to start with a double-dash, to distinguish them from standard properties and avoid naming collisions with future standards.

html {
  --theme-color: orange;
}

You can override the value of a custom property with higher priority selector.

.purple-theme {
  --theme-color: purple;
}

The value of a custom property can be any string. They are not limited to existing CSS property values. Non-standard property values are mainly useful together with JavaScript.

For example, in the following we define a custom property with non-standard values:

html {
  --modes: fullscreen, compact, split-50-50;
}

Using Custom Properties

You can use the var() function to get the value of a custom property.

.link {
  color: var(--theme-color);
}

You can also define a fallback value for cases where the custom property is not defined:

.link {
  color: var(--theme-color, blue);
}

Custom Properties and Shadow DOM

Custom properties are inherited by default, allowing them to “pierce” shadow DOM boundaries. This makes it possible to theme/style components from outside their local style scope (see Style Scopes), assuming a component is using a custom property in its local styles (with var()).

A use case for this is documented in Scoping Component Styles.

Using with JavaScript

In addition to CSS, custom properties are also available to be used from JavaScript using the standard getComputedStyle method.

For example:

// Returns '1rem' when the Lumo theme is used
window.getComputedStyle(document.querySelector('html'))
  .getPropertyValue('--lumo-font-size-m');

You can also assign the value of a custom property using JavaScript.

For example:

// Reduce the default font size in the Lumo theme
document.querySelector('html').style.setProperty('--lumo-font-size-m', '0.875rem');