DEV Community

Cover image for How to use CSS variables to create amazing theme transitions 🎨✨
Cătălin Onuțu
Cătălin Onuțu

Posted on • Edited on

How to use CSS variables to create amazing theme transitions 🎨✨

CSS variables

They are a great out-of-the-box tool that enables you to write cleaner and more reusable styles.

Similar to how variables are defined and referenced in code, you can declare a CSS variable on an element and then reference it in any of its children.

Example:



<body>
  <h1>I'm using CSS variables!</h1>
  <button id="theme-switcher">Me too</button>
</body>


Enter fullscreen mode Exit fullscreen mode


:root {
  --primaryColor: #0c9f9f;
  --secondaryColor: #043535;
  --backgroundColor: #eeeeee;
}
body {
  background-color: var(--backgroundColor);
}
h1 {
  color: var(--primaryColor);
}
button {
  font-size: 2rem;
  padding: 0.5em 1em;

  color: var(--primaryColor);
  background-color: var(--secondaryColor);
  border: 2px solid var(--primaryColor);
}


Enter fullscreen mode Exit fullscreen mode

Preview for the example above

See the beauty of it?

Apart from adding semantic value (--primaryColor is much easier to understand than #0c9f9f), they allow you to change their value once and cascade the change to all elements that use it.

But how can their value change?

Adding a dark theme

First, use some JavaScript to add a dark-theme class to the <body> element when clicking the button.



document.getElementById("theme-switcher")?.addEventListener("click", () => {
  document.documentElement.classList.toggle("dark-theme");
});


Enter fullscreen mode Exit fullscreen mode

Then, when dark-theme is present, overwrite the CSS variables previously defined.



:root.dark-theme {
  --primaryColor: #47c519;
  --secondaryColor: #0c2404;
  --backgroundColor: #111111;
}


Enter fullscreen mode Exit fullscreen mode

Let's see what happens when clicking the button.

Theme changes when clicking the button

It changes all the colors! 🎉

Animating theme changes

Colors change, but it's a bit sharp.

Let's make it more smooth by adding a transition to the properties that change.



* {
  transition-property: color, background-color, border-color;
  transition-duration: 0.5s;
  transition-timing-function: ease;
}


Enter fullscreen mode Exit fullscreen mode

Theme changes are animated

🎁 Bonus 🎁 Account for user's preferred theme

Most devices offer the ability to use a dark theme nowadays.
You should account for this user preference and render your website based on it straight away.

In order to do so, you can make use of the prefers-color-scheme CSS media feature.



@media (prefers-color-scheme: light) {
  :root {
    /* Configuration for light theme */
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    /* Configuration for dark theme */
  }
}


Enter fullscreen mode Exit fullscreen mode

Conclusion

Leveraging CSS variables provides a powerful and efficient way to manage styles in your web projects. The ability to define and reference variables in a clear, semantic manner not only enhances code readability but also enables easy theme customization.

By incorporating JavaScript, you can dynamically switch between themes, showcasing the true flexibility of CSS variables. The animated transitions add a polished touch, ensuring a smooth and visually appealing user experience.

Explore Further

If you're curious to see these concepts in action, I've implemented a more advanced and interactive theme switcher on my website.

Cătălin Onuțu | Web Developer

Experienced web developer passionate about crafting efficient, accessible, and fast digital solutions.

favicon catalinonutu.com

Share your work in the comments

If you found these insights useful or implemented them in your own projects, I'd love to see what you've come up with!

Top comments (9)

Collapse
 
davboy profile image
Daithi O’Baoill

Excellent, thanks

Collapse
 
wraith profile image
Jake Lundberg

nice article 😀 variables really have made this sort of thing way easier!

as you’ve shown here, it’s good practice to use the system settings as your default, but you also want the user selection to override that so they can have more granular control over their experience.

this subject also goes way deeper as you start to introduce selection persistence, SSR, and custom themes that go beyond just light and dark. maybe a follow up post??? 😉

again, nice aricle! and keep up the great work!

Collapse
 
cataon profile image
Cătălin Onuțu • Edited

selection persistence, SSR, and custom themes that go beyond just light and dark

Indeed, it becomes a bit more interesting when it comes to synchronizing default & opt-in preferences -- then persistence. 😁

I probably will come up with a follow-up post on these.
Thanks for the feedback and for this great suggestion!

Collapse
 
derick1530 profile image
Derick Zihalirwa

i can't wait to read it

Collapse
 
francescovetere profile image
Francesco Vetere

Very nice article! Thanks ☺️

Collapse
 
cataon profile image
Cătălin Onuțu

Thank you!
Since this is my first post, your comment motivates me to continue 😁

Collapse
 
francescovetere profile image
Francesco Vetere

Glad to hear that! 💪

Collapse
 
dsaga profile image
Dusan Petkovic

Thanks for the article, do you know if this "prefers-color-scheme" is configured in the browser settings somewhere? I remember that there was an attribute that can be added to the body tag or something to indicate which color scheme a user prefers...

Collapse
 
cataon profile image
Cătălin Onuțu

I believe it is an operating system level setting and the browser passes it onto loaded pages. That is happening on the combination of macOS & Chrome that I'm using. It could differ on other operating systems though.
my macOS theme settings

By the sounds of it, you might be referring to the color-scheme property.