CSS Variables and Custom Properties
## Learning Objectives
- Understand CSS custom properties
- Define and use CSS variables
- Create maintainable themes
- Master var() syntax and fallbacks
## Introduction
CSS custom properties (variables) let you store values for reuse:
```css
:root {
--primary-color: #007bff;
--font-size-base: 16px;
}
.button {
background-color: var(--primary-color);
font-size: var(--font-size-base);
}
```
## Defining Variables
### Global Scope
```css
:root {
--color-primary: #007bff;
--color-secondary: #6c757d;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 2rem;
}
```
### Local Scope
```css
.card {
--card-padding: 20px;
padding: var(--card-padding);
}
```
## Using Variables
### Basic Usage
```css
:root {
--brand-color: #007bff;
}
h1 {
color: var(--brand-color);
}
.button {
background-color: var(--brand-color);
}
```
### With Fallbacks
```css
.element {
color: var(--text-color, #333);
font-size: var(--font-size, 16px);
margin: var(--spacing, 1rem);
}
```
### Multiple Fallbacks
```css
.element {
margin: var(--custom-margin, var(--default-margin, 20px));
}
```
## Variable Naming
```css
:root {
/* Use descriptive names */
--color-text-primary: #333;
--color-background-body: #f5f5f5;
--spacing-section: 2rem;
/* Use kebab-case */
--font-size-large: 1.25rem;
--border-radius-small: 4px;
/* Prefix to avoid conflicts */
--btn-padding: 10px 20px;
--header-height: 60px;
}
```
## Dynamic Updates
### JavaScript Access
```javascript
// Get variable
const color = getComputedStyle(document.documentElement)
.getPropertyValue('--primary-color');
// Set variable
document.documentElement.style.setProperty('--primary-color', '#ff6600');
```
### CSS Changes
```css
[data-theme="dark"] {
--bg-color: #1a1a1a;
--text-color: #f0f0f0;
}
[data-theme="light"] {
--bg-color: #ffffff;
--text-color: #333333;
}
```
## Theming
### Base Theme
```css
:root {
--color-primary: #007bff;
--color-secondary: #6c757d;
--color-success: #28a745;
--color-danger: #dc3545;
--color-warning: #ffc107;
--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
--spacing: 1rem;
--border-radius: 0.25rem;
}
```
### Dark Theme
```css
[data-theme="dark"] {
--color-bg: #1a1a1a;
--color-text: #f0f0f0;
--color-border: #333;
--color-primary: #4d9fff;
--color-bg-card: #2a2a2a;
}
```
### Component Theming
```css
.button {
--btn-bg: var(--color-primary);
--btn-color: white;
--btn-padding: 0.5rem 1rem;
background-color: var(--btn-bg);
color: var(--btn-color);
padding: var(--btn-padding);
}
.button--secondary {
--btn-bg: var(--color-secondary);
}
.button--large {
--btn-padding: 1rem 2rem;
}
```
## Practical Example
```css
:root {
/* Colors */
--hue: 200;
--saturation: 100%;
--lightness: 50%;
--primary: hsl(var(--hue), var(--saturation), var(--lightness));
--primary-light: hsl(var(--hue), var(--saturation), 70%);
--primary-dark: hsl(var(--hue), var(--saturation), 30%);
/* Typography */
--font-base: 16px;
--font-scale: 1.25;
--font-size-sm: calc(var(--font-base) / var(--font-scale));
--font-size-md: var(--font-base);
--font-size-lg: calc(var(--font-base) * var(--font-scale));
--font-size-xl: calc(var(--font-base) * var(--font-scale) * var(--font-scale));
/* Spacing */
--space-unit: 1rem;
--space-xs: calc(var(--space-unit) * 0.25);
--space-sm: calc(var(--space-unit) * 0.5);
--space-md: var(--space-unit);
--space-lg: calc(var(--space-unit) * 2);
--space-xl: calc(var(--space-unit) * 4);
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 20px rgba(0, 0, 0, 0.15);
}
body {
font-size: var(--font-base);
margin: var(--space-md);
}
h1 { font-size: var(--font-size-xl); }
h2 { font-size: var(--font-size-lg); }
```
## Browser Support
```css
/* Fallback for older browsers */
.button {
background-color: #007bff; /* Fallback */
background-color: var(--primary);
}
```
## Summary
- CSS variables: `--variable-name: value;`
- Define in `:root` for global scope
- Use `var(--name)` or `var(--name, fallback)` syntax
- Dynamic updates via CSS or JavaScript
- Great for theming and design systems
- Always provide fallbacks for better browser support
- Use descriptive, kebab-case naming conventions
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →