CSS Variables Tutorial
Master CSS Custom Properties with comprehensive examples and practical implementations
What Are CSS Variables?
CSS Custom Properties (commonly called CSS Variables) are entities that contain specific values to be reused throughout a document. They follow the same scope and inheritance rules as other CSS properties.
Key Benefits:
- Reduce repetition in CSS code
- Make theme creation and switching easier
- Create dynamic styles with JavaScript integration
- Improve readability and maintainability
- Enable responsive design with variable changes
CSS Variables Implementation
Complete Example Code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CSS Variables Tutorial</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } :root { /* Color Variables */ --primary-color: #3498db; --secondary-color: #2ecc71; --accent-color: #e74c3c; --dark-color: #2c3e50; --light-color: #ecf0f1; --text-color: #333; --text-light: #fff; /* Spacing Variables */ --spacing-xs: 0.25rem; --spacing-sm: 0.5rem; --spacing-md: 1rem; --spacing-lg: 1.5rem; --spacing-xl: 2rem; /* Typography Variables */ --font-main: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; --font-heading: 'Arial', sans-serif; --font-size-sm: 0.875rem; --font-size-md: 1rem; --font-size-lg: 1.25rem; --font-size-xl: 1.5rem; --font-size-xxl: 2rem; /* Border Variables */ --border-radius: 0.5rem; --border-width: 2px; --border-style: solid; /* Shadow Variables */ --shadow-sm: 0 2px 4px rgba(0,0,0,0.1); --shadow-md: 0 4px 6px rgba(0,0,0,0.1); --shadow-lg: 0 10px 15px rgba(0,0,0,0.1); /* Transition Variables */ --transition-fast: 0.2s ease; --transition-normal: 0.3s ease; --transition-slow: 0.5s ease; /* Layout Variables */ --max-width: 1200px; --header-height: 70px; --sidebar-width: 250px; } body { font-family: var(--font-main); line-height: 1.6; color: var(--text-color); background-color: var(--light-color); padding: var(--spacing-md); } .container { max-width: var(--max-width); margin: 0 auto; } header { text-align: center; margin-bottom: var(--spacing-xl); padding: var(--spacing-lg); background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: var(--text-light); border-radius: var(--border-radius); box-shadow: var(--shadow-md); } h1 { font-family: var(--font-heading); font-size: var(--font-size-xxl); margin-bottom: var(--spacing-sm); } h2 { font-family: var(--font-heading); font-size: var(--font-size-xl); margin: var(--spacing-lg) 0 var(--spacing-md); color: var(--dark-color); padding-bottom: var(--spacing-sm); border-bottom: var(--border-width) var(--border-style) var(--primary-color); } h3 { font-size: var(--font-size-lg); margin: var(--spacing-md) 0; color: var(--primary-color); } .example { background: white; border-radius: var(--border-radius); padding: var(--spacing-lg); margin-bottom: var(--spacing-lg); box-shadow: var(--shadow-sm); } .demo { border: var(--border-width) var(--border-style) #e9ecef; border-radius: var(--border-radius); padding: var(--spacing-lg); margin: var(--spacing-md) 0; background: #f8f9fa; } .code-block { background: #2d2d2d; color: #f8f8f2; padding: var(--spacing-md); border-radius: var(--border-radius); overflow-x: auto; margin: var(--spacing-md) 0; font-family: 'Consolas', 'Monaco', monospace; font-size: var(--font-size-sm); } .btn { display: inline-block; padding: var(--spacing-sm) var(--spacing-md); background: var(--primary-color); color: var(--text-light); border: none; border-radius: var(--border-radius); cursor: pointer; font-size: var(--font-size-sm); margin-right: var(--spacing-sm); transition: background-color var(--transition-fast); } .btn:hover { background: #2980b9; } .btn-copy { background: var(--secondary-color); } .btn-copy:hover { background: #27ae60; } /* Example 1: Basic Variable Usage */ .basic-usage { padding: var(--spacing-md); background-color: var(--primary-color); color: var(--text-light); border-radius: var(--border-radius); margin-bottom: var(--spacing-md); } .basic-usage-alt { padding: var(--spacing-md); background-color: var(--secondary-color); color: var(--text-light); border-radius: var(--border-radius); } /* Example 2: Component Scoped Variables */ .card { --card-bg: white; --card-padding: var(--spacing-md); --card-border: var(--border-width) var(--border-style) #ddd; background: var(--card-bg); padding: var(--card-padding); border: var(--card-border); border-radius: var(--border-radius); margin-bottom: var(--spacing-md); box-shadow: var(--shadow-sm); } .card.featured { --card-bg: #fffaf0; --card-border: var(--border-width) var(--border-style) var(--accent-color); } /* Example 3: Theming with Variables */ .theme-example { --theme-bg: var(--light-color); --theme-text: var(--text-color); --theme-border: #ccc; padding: var(--spacing-md); background: var(--theme-bg); color: var(--theme-text); border: var(--border-width) var(--border-style) var(--theme-border); border-radius: var(--border-radius); margin-bottom: var(--spacing-md); transition: all var(--transition-normal); } .theme-example.dark { --theme-bg: var(--dark-color); --theme-text: var(--text-light); --theme-border: #555; } /* Example 4: Dynamic Variables with JavaScript */ .dynamic-example { padding: var(--spacing-lg); background: var(--dynamic-bg, var(--primary-color)); color: var(--dynamic-text, white); border-radius: var(--border-radius); margin-bottom: var(--spacing-md); transition: background-color var(--transition-normal); } .controls { display: flex; gap: var(--spacing-sm); margin-bottom: var(--spacing-md); flex-wrap: wrap; } .control-btn { padding: var(--spacing-xs) var(--spacing-sm); background: var(--primary-color); color: white; border: none; border-radius: var(--border-radius); cursor: pointer; } /* Example 5: Responsive Variables */ .responsive-example { padding: var(--spacing-md); background: var(--responsive-bg, #f0f0f0); color: var(--responsive-text, #333); border-radius: var(--border-radius); margin-bottom: var(--spacing-md); } @media (min-width: 768px) { .responsive-example { --responsive-bg: #e0f7fa; --responsive-text: #006064; } } @media (min-width: 1024px) { .responsive-example { --responsive-bg: #fff3e0; --responsive-text: #e65100; } } /* Example 6: Using calc() with Variables */ .calc-example { --base-size: 16px; --multiplier: 2; font-size: calc(var(--base-size) * var(--multiplier)); padding: calc(var(--spacing-md) * 2); background: var(--primary-color); color: white; border-radius: var(--border-radius); margin-bottom: var(--spacing-md); text-align: center; } /* Example 7: Gradient Variables */ .gradient-example { --gradient-direction: to right; --gradient-start: var(--primary-color); --gradient-end: var(--secondary-color); padding: var(--spacing-lg); background: linear-gradient(var(--gradient-direction), var(--gradient-start), var(--gradient-end)); color: white; border-radius: var(--border-radius); margin-bottom: var(--spacing-md); text-align: center; } /* Example 8: Animation with Variables */ @keyframes pulse { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(var(--pulse-scale, 1.05)); opacity: 0.8; } 100% { transform: scale(1); opacity: 1; } } .animation-example { --pulse-scale: 1.1; --animation-duration: 2s; padding: var(--spacing-lg); background: var(--accent-color); color: white; border-radius: var(--border-radius); margin-bottom: var(--spacing-md); text-align: center; animation: pulse var(--animation-duration) infinite; } /* Example 9: Fallback Values */ .fallback-example { padding: var(--spacing-md); background: var(--non-existent-variable, #ff9800); color: var(--also-non-existent, white); border-radius: var(--border-radius); margin-bottom: var(--spacing-md); text-align: center; } /* Example 10: Complex System */ .complex-system { --system-spacing: var(--spacing-md); --system-color: var(--primary-color); --system-shadow: var(--shadow-md); padding: calc(var(--system-spacing) * 2); background: color-mix(in srgb, var(--system-color) 20%, white); border: var(--border-width) var(--border-style) var(--system-color); border-radius: var(--border-radius); box-shadow: var(--system-shadow); margin-bottom: var(--spacing-md); } .complex-system.alternate { --system-spacing: var(--spacing-lg); --system-color: var(--secondary-color); --system-shadow: var(--shadow-lg); } </style> </head> <body> <div class="container"> <header> <h1>CSS Variables Tutorial</h1> <p>Master CSS Custom Properties with Practical Examples</p> </header> <section class="example"> <h2>1. Basic Variable Usage</h2> <p>CSS variables (custom properties) are defined with a double hyphen prefix and accessed with the var() function.</p> <div class="demo"> <div class="basic-usage">This uses --primary-color variable</div> <div class="basic-usage-alt">This uses --secondary-color variable</div> </div> <div class="code-block"> :root { --primary-color: #3498db; --secondary-color: #2ecc71; } .basic-usage { background-color: var(--primary-color); color: white; } .basic-usage-alt { background-color: var(--secondary-color); color: white; } </div> </section> <section class="example"> <h2>2. Component Scoped Variables</h2> <p>Variables can be scoped to specific components, allowing for local overrides.</p> <div class="demo"> <div class="card">Regular Card</div> <div class="card featured">Featured Card (with overridden variables)</div> </div> <div class="code-block"> .card { --card-bg: white; --card-padding: 1rem; --card-border: 2px solid #ddd; background: var(--card-bg); padding: var(--card-padding); border: var(--card-border); } .card.featured { --card-bg: #fffaf0; --card-border: 2px solid var(--accent-color); } </div> </section> <section class="example"> <h2>3. Theming with Variables</h2> <p>CSS variables make creating themes incredibly easy with minimal code.</p> <div class="demo"> <div class="theme-example">Default Theme</div> <div class="theme-example dark">Dark Theme</div> </div> <div class="code-block"> .theme-example { --theme-bg: var(--light-color); --theme-text: var(--text-color); --theme-border: #ccc; background: var(--theme-bg); color: var(--theme-text); border: 2px solid var(--theme-border); } .theme-example.dark { --theme-bg: var(--dark-color); --theme-text: var(--text-light); --theme-border: #555; } </div> </section> <section class="example"> <h2>4. Dynamic Variables with JavaScript</h2> <p>CSS variables can be updated dynamically with JavaScript for interactive experiences.</p> <div class="demo"> <div class="dynamic-example" id="js-example"> This element's styles can be changed dynamically </div> <div class="controls"> <button onclick="changeColor('#3498db')">Blue</button> <button onclick="changeColor('#e74c3c')">Red</button> <button onclick="changeColor('#2ecc71')">Green</button> <button onclick="changeColor('#f39c12')">Orange</button> <button onclick="changeTextColor('#fff')">White Text</button> <button onclick="changeTextColor('#ff0')">Yellow Text</button> </div> </div> <div class="code-block"> .dynamic-example { background: var(--dynamic-bg, #3498db); color: var(--dynamic-text, white); } // JavaScript to change variables function changeColor(color) { document.getElementById('js-example') .style.setProperty('--dynamic-bg', color); } function changeTextColor(color) { document.getElementById('js-example') .style.setProperty('--dynamic-text', color); } </div> </section> <section class="example"> <h2>5. Responsive Variables</h2> <p>Variables can be redefined in media queries for responsive designs.</p> <div class="demo"> <div class="responsive-example"> Resize the browser to see my colors change </div> </div> <div class="code-block"> .responsive-example { background: var(--responsive-bg, #f0f0f0); color: var(--responsive-text, #333); } @media (min-width: 768px) { .responsive-example { --responsive-bg: #e0f7fa; --responsive-text: #006064; } } @media (min-width: 1024px) { .responsive-example { --responsive-bg: #fff3e0; --responsive-text: #e65100; } } </div> </section> <section class="example"> <h2>6. Using calc() with Variables</h2> <p>CSS variables work perfectly with the calc() function for dynamic calculations.</p> <div class="demo"> <div class="calc-example"> My size is calculated using variables! </div> </div> <div class="code-block"> .calc-example { --base-size: 16px; --multiplier: 2; font-size: calc(var(--base-size) * var(--multiplier)); padding: calc(1rem * 2); } </div> </section> <section class="example"> <h2>7. Gradient Variables</h2> <p>Create dynamic gradients using CSS variables.</p> <div class="demo"> <div class="gradient-example"> Gradient using CSS variables </div> </div> <div class="code-block"> .gradient-example { --gradient-direction: to right; --gradient-start: var(--primary-color); --gradient-end: var(--secondary-color); background: linear-gradient( var(--gradient-direction), var(--gradient-start), var(--gradient-end) ); } </div> </section> <section class="example"> <h2>8. Animation with Variables</h2> <p>Control animations with variables for more dynamic effects.</p> <div class="demo"> <div class="animation-example"> Pulsing with variable control </div> </div> <div class="code-block"> @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(var(--pulse-scale, 1.05)); } 100% { transform: scale(1); } } .animation-example { --pulse-scale: 1.1; --animation-duration: 2s; animation: pulse var(--animation-duration) infinite; } </div> </section> <section class="example"> <h2>9. Fallback Values</h2> <p>The var() function accepts a fallback value for when a variable is not defined.</p> <div class="demo"> <div class="fallback-example"> This uses fallback values </div> </div> <div class="code-block"> .fallback-example { /* These variables are not defined, so fallbacks are used */ background: var(--non-existent-variable, #ff9800); color: var(--also-non-existent, white); } </div> </section> <section class="example"> <h2>10. Complex System</h2> <p>Building a complex design system with interconnected variables.</p> <div class="demo"> <div class="complex-system"> Standard System Component </div> <div class="complex-system alternate"> Alternate System Component </div> </div> <div class="code-block"> .complex-system { --system-spacing: 1rem; --system-color: var(--primary-color); --system-shadow: var(--shadow-md); padding: calc(var(--system-spacing) * 2); background: color-mix(in srgb, var(--system-color) 20%, white); border: 2px solid var(--system-color); box-shadow: var(--system-shadow); } .complex-system.alternate { --system-spacing: 1.5rem; --system-color: var(--secondary-color); --system-shadow: var(--shadow-lg); } </div> </section> </div> <script> function changeColor(color) { document.getElementById('js-example') .style.setProperty('--dynamic-bg', color); } function changeTextColor(color) { document.getElementById('js-example') .style.setProperty('--dynamic-text', color); } </script> </body> </html>
Key CSS Variables Concepts
Syntax & Definition
- Define with:
--variable-name: value;
- Access with:
var(--variable-name)
- Provide fallbacks:
var(--name, fallback)
- Use in calculations:
calc(var(--size) * 2)
- Scope to elements for local overrides
Scope & Inheritance
- Global scope with
:root
selector - Local scope with element selectors
- Variables follow CSS inheritance rules
- Can be redefined in media queries
- JavaScript can access and modify values
CSS Variables Best Practices
Do's
- Use semantic variable names (--color-primary, not --blue)
- Define global variables in the
:root
selector - Use fallback values for better resilience
- Group related variables together
- Leverage variables for theming and consistency
Don'ts
- Don't overuse variables for one-off values
- Avoid deeply nested variable dependencies
- Don't forget to provide appropriate fallbacks
- Avoid naming conflicts with careful scoping
- Don't use variables for values that won't be reused
Real-World Applications
Where to Use CSS Variables
- Design Systems: Maintain consistency across large projects
- Theming: Create light/dark mode or brand variations
- Responsive Design: Change values at different breakpoints
- Dynamic UI: Modify styles with JavaScript interactions
- Spacing & Layout: Consistent spacing throughout application
- Animation Control: Parameterize animation properties
Browser Support & Fallbacks
Compatibility Information
CSS Variables are supported in all modern browsers, but it's important to provide fallbacks for older browsers.
- Supported in all modern browsers (Chrome, Firefox, Safari, Edge)
- Not supported in Internet Explorer
- Use
@supports
rule for feature detection - Provide static fallback values before variable declarations
- Consider using CSS preprocessors for legacy browser support
Ready to Experiment with CSS Variables?
Try these CSS Variables examples in our interactive editor. Modify the code, see the results in real-time, and practice implementing variables in your projects.