Many web applications contain large amounts of CSS, which often contain repeated values. For example, if a color is used multiple times in a number of components, in order to change the color, a global search and replace is initiated. This can be both time consuming and rather daunting.
Custom properties allow developers to store values in a single file and reference that value in many components. Custom properties also allow for semantic identifiers, for example --main-button-color
will be better understood than #99efbe
if used in multiple components. It’s also important to note custom properties are subject to the CSS cascading rules.
In this article, I will give a brief overview of CSS custom properties and how to use them, as well as discuss their functionality with JavaScript, APIs, and React.
Custom properties, also known as CSS variables, are specific values that are defined by a developer to be reused in a web application or document. Usually CSS variables are set using property notation.
An example of a basic custom property can be seen below:
button { background-color: var(--main-bg-color); }
In the code block above, the button element is assigned a background color of main
, which has already been defined in a separate file. Let’s see how to use a custom property below.
To declare a custom property, first we declare the property name by adding a double hyphen (--)
next to a valid CSS value.
Like any other variable, we write this inside a ruleset like the snippet below:
element { --main-color: red; }
To use a value in a property declaration, we need to call it with a var()
function like the code block below:
p { color: var(--color-primary); }
It’s important to note that the selectors given to the ruleset define the scope in which the custom property can be used. Another common usage is to define the scope of your custom property as :root
, its global. This is done so it can be applied globally across many documents and components.
In this section, we’ll be looking at the use cases for custom properties and CSS variables.
Colors can be set as CSS custom properties. This example will include scopes for custom properties for color changes.
In our case, we can define a color danger
red for a particular element, say, h2
. However, the application also uses an h2
element for the subtitles in the <article>
navbar.
We can declare the --color-love
value in an <article>
. Now any <h2>
in a subtitle will be blue instead of red:
:root { --color-danger: red; } h2 { color: var(--color-danger); } article { --color-love: #0000FF; }
Font sizes are another way to use custom properties, because font sizes can be changed using CSS scoping.
An example of this can be found in the same way as the above example:
:root { --heading-size: 24px; } h2 { font-size: var(--heading-size); } article { --heading-size: 18px; }
In the code block above, the global heading size was set to 24px
. In the article
selector, we updated it to 18px
.
Grid layouts are one of the most modern trends in web development. We can use CSS custom properties to set up custom layouts for our grid, like in the following code block:
:root { --grid-width: 30%; } .grid-box { align-items: flex-end; width: var(--grid-width); } .product-grid { --grid-width: 35%; }
Buttons are a great way to use custom CSS properties. An example of this can be seen when a button is styled globally and can be updated with another custom value as seen below:
:root { --button-color: blue; --button-color-white: white; --button-color-danger: red; } .button { background-color: var(--button-color); box-shadow: 2px 4px 0 var(--button-color-dark); } .button:hover { background-color: var(--button-color-dark); box-shadow: 0 0 0 var(--button-color-dark); } .form { --button-color: #ff571c; --button-color-dark: #cc5600; --button-color-light: #ffb64f; }
Custom CSS properties can be changed in real time using JavaScript. This is nice when building user enabled themes, changing or demoing multiple layouts, or changing color schemes for a user.
CSS custom properties can be used for changing the state of any application like the code block below:
const body = document.getElementByTagName("body")[0]; function change_vars(){ if (!body.classsList.contains('changed') ) { body.style.setProperty('--color-primary', '#ff54ef'); body.classList.add('changed'); } else { body.style.setProperty('--color-primary', '#13efdc'); body.classList.remove('changed'); } }
CSS custom properties can be used as API especially if they’re hosted as CDNs.
Let’s look at the code block below:
// today's special is .today::after { content: var(--todaysSpecial); }
The code block above can be used to like an API, making it easy to use, however this is challenging and isn’t very accessible.
CSS custom properties can be used in React applications, which can unlock new possibilities for React developers. With CSS variables you can do a number of things that are not possible with JavaScript.
To use custom properties in a React application, first you’d need a single file. In our case, constants.js
, to hold all our design tokens similar to the one below:
const SIZES = [ 4, 8, 12, 16, 20, 24, 28, 32, 36 ]; const COLORS = { text: 'black', background: 'white', primary: 'purple', secondary: 'blue' };
Next, you import the file directly into your components as seen in the code block below:
import { COLORS } from '../constant'; const Button = styled.button` background: ${COLORS.secondary}; `;
With CSS variables, we can do more with variables, and instead of changing them, we can only change the values wherever we need to.
In this next section, we’ll talk about a notable library that makes it easier for developers to perform custom properties on React applications.
React Custom Properties is a React component for applying CSS variables. With React Custom Properties, developers can declaratively apply CSS custom properties.
React Custom Properties can be installed using a node package manager using the command below:
npm install react-custom-properties
Next, import the CustomProperties
like so:
import CustomProperties from 'react-custom-properties';
React Custom Properties provides a <CustomProperties/>
component, which can be used to apply CSS variables that are passed to the properties
to its children when mounted.
We can use it as follows:
import React, { Component } from 'react'; import CustomProperties from 'react-custom-properties'; class App extends Component { render() { return { <div> <CustomProperties properties={{ '--branding-color': '#000FFE' }}> <div className="navbar"> this will have the background color #000FFE </div> </CustomProperties> </div> ); } }
React Custom Properties also supports nesting so that parent instances can be overridden by child instances. You can learn more about React Custom Properties here.
Custom CSS properties help users to not only define layouts, but also update CSS values and variables in applications.
Although in its experimental stage, CSS variables can be used as API and to control JavaScript state. Libraries like React Custom Properties make it easier to use custom variables in React applications.
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — start monitoring for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to implement one-way and two-way data binding in Vue.js, using v-model and advanced techniques like defineModel for better apps.
Compare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.