DEV Community

Cover image for 180 Days of Frontend Development Challenge: Day 39 CSS Variables and Custom Properties
CodeWithDhanian
CodeWithDhanian

Posted on

180 Days of Frontend Development Challenge: Day 39 CSS Variables and Custom Properties

Welcome back, focused developer. Over the past few days, we explored transitions and animations to bring interfaces to life. Today, we shift toward the foundation of scalable styling: CSS Variables (also known as Custom Properties). These are not just a syntactic trick — they’re a cornerstone for building maintainable, themeable, and systematized design systems.

→ Why CSS Variables Matter

Before CSS variables, global consistency meant either copy-pasting values throughout your stylesheets or managing complex preprocessor workflows (e.g., Sass). If your brand color changed, you needed to find and replace every instance manually — error-prone and time-consuming.

With CSS Variables:

  • You define once, reuse everywhere.
  • You create design tokens (colors, spacing, font stacks, etc.).
  • You enable theming without rewriting styles.
  • You gain dynamic capabilities like conditionally overriding values.

→ Core Concepts to Understand

→ What Are CSS Variables?

CSS variables are custom properties that follow the syntax --property-name: value; and are accessed with var(--property-name).

:root {
  --primary-color: #3498db;
  --font-stack: Arial, sans-serif;
}
Enter fullscreen mode Exit fullscreen mode
  • They are case-sensitive (--main-color--Main-Color)
  • The :root pseudo-class allows global definition (equivalent to the <html> element)
  • You can also declare them locally within a specific selector for scoped usage

→ Variable Usage with var()

body {
  font-family: var(--font-stack);
  background-color: var(--background-color, #f0f0f0); /* fallback */
}
Enter fullscreen mode Exit fullscreen mode

You can pass a fallback as a second argument if the variable isn’t defined.

→ Scope and Inheritance

  • Variables declared in :root are global
  • Variables declared within a component/class are scoped to that element and its descendants
.theme-light {
  --text-color: #f0f0f0;
}
.theme-dark {
  --text-color: #333;
}
Enter fullscreen mode Exit fullscreen mode
p {
  color: var(--text-color);
}
Enter fullscreen mode Exit fullscreen mode

Changing the class on a parent element changes the styles across all children using that variable.

→ Dynamic Calculation with calc()

You can combine CSS variables with calc() for responsive design:

:root {
  --sidebar-width: 250px;
}

.main-content {
  width: calc(100% - var(--sidebar-width));
}
Enter fullscreen mode Exit fullscreen mode

This is ideal for layout adjustments, responsive containers, or when working with grids.

→ Example: Themeable Layout with CSS Variables

Let’s look at a modular example with reusable design tokens:

HTML

<div class="page-container">
  <header class="main-header">...</header>
  <main class="main-content">...</main>
  <footer class="main-footer">...</footer>
</div>

<div class="theme-switcher">
  <button id="light-theme">Light Theme</button>
  <button id="dark-theme">Dark Theme</button>
</div>
Enter fullscreen mode Exit fullscreen mode

CSS (Simplified for Focus)

:root {
  --primary-color: #3498db;
  --secondary-color: #2ecc71;
  --font-family: 'Inter', sans-serif;
  --text-color: #333;
  --background-color: #f4f4f4;
  --spacing-md: 24px;
  --border-radius: 8px;
}

body {
  background-color: var(--background-color);
  font-family: var(--font-family);
  color: var(--text-color);
}

.button {
  background-color: var(--primary-color);
  padding: var(--spacing-md);
  border-radius: var(--border-radius);
  color: white;
}

body.dark-theme {
  --primary-color: #6dd5ed;
  --secondary-color: #a4e5a9;
  --text-color: #f0f0f0;
  --background-color: #2c3e50;
}
Enter fullscreen mode Exit fullscreen mode

Theme Switching (JavaScript)

document.addEventListener('DOMContentLoaded', () => {
  document.getElementById('dark-theme').onclick = () =>
    document.body.classList.add('dark-theme');

  document.getElementById('light-theme').onclick = () =>
    document.body.classList.remove('dark-theme');
});
Enter fullscreen mode Exit fullscreen mode

→ Key Techniques to Implement

  1. Global Declaration
    → Use :root to declare all essential design tokens (colors, fonts, spacing, etc.)

  2. Component Scoping
    → Use local custom properties for reusable UI components or specific elements

  3. Theme Switching
    → Override root-level variables using contextual classes like .dark-theme, .light-theme

  4. Fallbacks
    → Always provide defaults with var(--property, fallback)

  5. Dynamic Sizing
    → Combine variables with calc() to maintain responsive design and proportional spacing

→ Challenge for Day 39

  1. Choose an existing project or create a new one (e.g., portfolio, blog, landing page).
  2. Identify at least 5–7 repeating CSS values:
  • Colors, font sizes, paddings, margins, shadows, radii

    1. Move them into :root as CSS variables
    2. Replace all hardcoded values with var(--property-name)
    3. Implement a theme switcher that toggles between light and dark mode
  • Override variables inside a .dark-theme class

    1. Bonus:
  • Add component-scoped variables to isolate customization

  • Use calc() with your variables to create dynamic layout behavior

→ Going Further

This modular use of CSS variables unlocks scalable styling across any design system. It makes it easier to maintain large codebases, implement themes, and work in teams. Combined with utility-first or component-based architectures (like BEM, CSS Modules, or Tailwind), variables serve as the backbone for consistency.

To explore deeper and advance your front-end skills, consider reading:
“The Ultimate Guide to Responsive Web Design” by Dhanian
🔗 https://codewithdhanian.gumroad.com/l/sxpyzb

→ Final Thought

CSS Variables aren’t just a tool — they’re a shift in how you think about styling. They're declarative, powerful, and enable true design systems at the CSS level. Adopt them now, and your future self will thank you.

Let’s keep going. You're laying down the foundations for professional-grade frontend development.

Top comments (0)