Introduction
In frontend development, the ability to switch between light and dark modes is becoming a necessity. This article explains how to efficiently implement this feature using CSS Custom Properties, also known as CSS variables (var()
).
Why Use CSS Variables?
The biggest advantage of CSS variables is their maintainability and scalability. For example, by defining a theme color in one place, like --color-background-primary: #ffffff;
, you can use that variable throughout your entire site.
:root {
--color-background-primary: #ffffff;
--color-text-primary: #000000;
}
body {
background-color: var(--color-background-primary);
color: var(--color-text-primary);
}
This way, if you want to switch themes, you only need to change the variable values by adding a class like [data-theme='dark']
to the :root
or body
tag.
Combining with SCSS
In my blog project "Nurohive," I use SCSS
to implement theme switching. By combining SCSS
variables and CSS variables, I can further organize and manage color definitions.
Here is an excerpt from _theme_variables.scss
where theme colors are defined.
// nurohive-next/src/app/styles/_theme_variables.scss
// Define light mode theme colors
$light-theme: (
color-background-primary: #f6f6f6,
color-background-secondary: #ffffff,
color-text-primary: #121212,
color-link-hover: #007bff,
color-border-primary: #e0e0e0,
);
// Define dark mode theme colors
$dark-theme: (
color-background-primary: #121212,
color-background-secondary: #1a1a1a,
color-text-primary: #f6f6f6,
color-link-hover: #007bff,
color-border-primary: #333333,
);
// Mixin to output as CSS Custom Properties
@mixin set-theme($theme) {
@each $key, $value in $theme {
--#{$key}: #{$value};
}
}
// Manage theme switching
[data-theme="light"] {
@include set-theme($light-theme);
}
[data-theme="dark"] {
@include set-theme($dark-theme);
}
This SCSS
code uses a mixin to convert the $light-theme
and $dark-theme
maps into CSS custom properties. By doing so, simply toggling the [data-theme='dark']
attribute on the HTML tag will dynamically change the site's entire style.
Implementation Steps
Here are the specific implementation steps:
- Create SCSS files:
- Create
_theme_variables.scss
andglobal-styles.scss
.
- Create
- Define theme variables:
- Define the light and dark mode colors as
SCSS
maps in_theme_variables.scss
.
- Define the light and dark mode colors as
- Convert to CSS Custom Properties:
- Use a mixin to convert the
SCSS
maps into CSS Custom Properties and link them to the[data-theme]
attribute.
- Use a mixin to convert the
- Implement a
useTheme
component:- Use
Next.js
'scontext
oruseState
to create a component that manages the theme state. This component will be responsible for dynamically adding attributes like[data-theme='dark']
to the<html>
tag.
- Use
- Import into
_app.tsx
orlayout.tsx
:- Import the created
global-styles.scss
intolayout.tsx
to apply the styles to the entire site.
- Import the created
Conclusion
Using CSS Custom Properties makes the theme-switching feature dramatically simpler. Understanding this mechanism is essential for building a design system and creating maintainable frontend applications in future projects.
I hope this development log helps you on your own journey to "survive setup hell."