CSS - Custom Properties
Syntax and Usage
Declaring Custom Properties
To declare a custom property in CSS, you use the double-dash (--
) syntax followed by the name of the property. You define custom properties inside a CSS ruleset or the :root
pseudo-class, which represents the root element of the document tree.
Example: Declaring Custom Properties
:root {
--primary-color: #007bff;
--font-size: 16px;
--spacing: 1rem;
}
We declare three custom properties: --primary-color
, --font-size
, and --spacing
. We assign them values of #007bff
, 16px
, and 1rem
, respectively. By declaring custom properties in the :root
pseudo-class, they become globally accessible throughout the document.
Using Custom Properties
To use a custom property, you reference it using the var()
function. The var()
function allows you to get the value of a custom property and use it as a value for another CSS property.
Example: Using Custom Properties
.button {
background-color: var(--primary-color);
font-size: var(--font-size);
padding: var(--spacing);
}
We apply the custom properties to the .button
class. The background-color
property is set to the value of --primary-color
, the font-size
property is set to the value of --font-size
, and the padding
property is set to the value of --spacing
. The var()
function retrieves the corresponding values of the custom properties.
Scope and Inheritance
Custom properties follow the same scoping and inheritance rules as other CSS properties. They are subject to the cascade and can be overridden by more specific rules. Custom properties defined in a parent element are inherited by its child elements.
Example: Scope and Inheritance
:root {
--text-color: black;
}
.container {
--text-color: blue;
}
.container p {
color: var(--text-color);
}
We define the --text-color
custom property in the :root
pseudo-class with a value of black
. We then redefine --text-color
inside the .container
class with a value of blue
. The <p>
elements inside the .container
will inherit the value of --text-color
from the nearest ancestor, which is .container
. As a result, the text color of the paragraphs inside .container
will be blue, while paragraphs outside of .container
will have the default black color.
By using the scoping and inheritance behavior of custom properties, you can create modular and reusable styles in your CSS code.
Practical Examples
Theming
Custom properties give a way to implement theming in your CSS. By defining custom properties for theme colors, you can switch between different color schemes without changing the individual CSS rules.
Example: Define Custom Properties for Theming
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--text-color: #333;
--background-color: #fff;
}
.dark-theme {
--primary-color: #0056b3;
--secondary-color: #495057;
--text-color: #fff;
--background-color: #222;
}
body {
color: var(--text-color);
background-color: var(--background-color);
}
.button {
background-color: var(--primary-color);
color: var(--background-color);
}
We define custom properties for the primary color, secondary color, text color, and background color in the :root
pseudo-class. These are the default theme colors. We then define a .dark-theme
class that overrides the values of the custom properties to create a dark theme.
By applying the .dark-theme
class to the <body>
element, you can switch the entire theme of your website. The color
and background-color
of the <body>
and the .button
class will adapt to the new theme colors.
You can switch themes using JavaScript by toggling the .dark-theme
class on the <body>
element.
Example: Switch Themes with JavaScript
const body = document.body;
const toggleThemeButton = document.getElementById('toggleTheme');
toggleThemeButton.addEventListener('click', () => {
body.classList.toggle('dark-theme');
});
Responsive Design
Custom properties can be used for responsive design by letting you adjust styles based on screen size. You can update the values of custom properties using media queries to change the look of your website at different breakpoints.
Example: Responsive Design with Custom Properties
:root {
--font-size: 16px;
--spacing: 1rem;
}
@media (max-width: 768px) {
:root {
--font-size: 14px;
--spacing: 0.75rem;
}
}
.container {
font-size: var(--font-size);
padding: var(--spacing);
}
We define custom properties --font-size
and --spacing
with default values. Then, we use a media query to update their values when the screen width is less than or equal to 768px. The .container
class will adapt its font-size
and padding
based on the screen size.
Reusable Components
Custom properties let you create reusable UI components with flexible styling. By defining custom properties for component-specific styles, you can customize the look of components without changing their individual CSS rules.
Example: Create Reusable UI Components
.button {
--button-color: #007bff;
--button-text-color: #fff;
--button-padding: 0.5rem 1rem;
background-color: var(--button-color);
color: var(--button-text-color);
padding: var(--button-padding);
}
.primary-button {
--button-color: #28a745;
}
.large-button {
--button-padding: 1rem 2rem;
}
We create a .button
class with custom properties for the button color, text color, and padding. These custom properties are the default styles for the button.
To create variations of the button, we define additional classes like .primary-button
and .large-button
that override specific custom properties. This lets you customize the button styles without copying the entire CSS rule.
By combining these classes, you can create buttons with different colors and sizes while keeping a consistent base style.
Custom properties give a flexible and maintainable way to build reusable UI components in your CSS code.
Combining with Other CSS Features
Using Custom Properties with CSS Preprocessors (Sass, Less)
Custom properties work with CSS preprocessors such as Sass and Less. These preprocessors give more features and flexibility in writing CSS code. When using custom properties with preprocessors, you can use variables, functions, and mixins.
Sass supports custom properties from version 4.0 and later. You can define custom properties in Sass using the $
syntax for variables.
Sass Example
$primary-color: #007bff;
:root {
--primary-color: #{$primary-color};
}
.button {
background-color: var(--primary-color);
}
We define a Sass variable $primary-color
with the value #007bff
. Then, we use the interpolation syntax #{$variable}
to assign the value of the Sass variable to the --primary-color
custom property. The .button
class can then use the custom property as usual.
Less also supports custom properties in a similar way. You can define custom properties using the @
syntax for variables.
Less Example
@primary-color: #007bff;
:root {
--primary-color: @primary-color;
}
.button {
background-color: var(--primary-color);
}
We define a Less variable @primary-color
with the value #007bff
. We assign the value of the Less variable directly to the --primary-color
custom property. The usage of the custom property remains the same.
Using custom properties with CSS preprocessors lets you use the features of the preprocessor while still benefiting from the dynamic nature of custom properties in the generated CSS.
Integrating Custom Properties with CSS-in-JS Libraries
Custom properties can also be integrated with CSS-in-JS libraries such as styled-components and emotion. These libraries allow writing CSS code directly in JavaScript, providing a more component-based approach to styling.
When using custom properties with CSS-in-JS libraries, you can define and use them within the JavaScript code.
CSS-in-JS Example (Styled Components)
import styled from 'styled-components';
const Button = styled.button`
--button-color: #007bff;
--button-text-color: #fff;
background-color: var(--button-color);
color: var(--button-text-color);
padding: 0.5rem 1rem;
`;
const PrimaryButton = styled(Button)`
--button-color: #28a745;
`;
We define custom properties --button-color
and --button-text-color
within the Button
component. These custom properties are used to style the button. We then create a PrimaryButton
component that extends the Button
component and overrides the --button-color
custom property.
By integrating custom properties with CSS-in-JS libraries, you can use the power of custom properties while enjoying the component-based architecture and JavaScript functionality provided by these libraries. Custom properties provide a flexible and interoperable way to combine them with other CSS features and tools, enabling you to write more modular and maintainable CSS code.