Skip to main content

Stop separating CSS files! Why Dark Mode should use Semantic Tokens instead of duplicated code

Deep dive into the issues of separated Dark Mode files that make projects hard to maintain, along with solutions using Semantic Tokens and a sustainable CSS architecture

AI-written
Inewgen
24 Jul 2026Source: Dev.to3 min read (0 views)Last updated 04 Aug 2026
Share
Stop separating CSS files! Why Dark Mode should use Semantic Tokens instead of duplicated code

Stock photo for illustration only, not from the actual event

Font size
  • Separating CSS files for Dark Mode alone causes code duplication and hard maintenance as applications grow.
  • Using Semantic Tokens allows components to remain unaware of which theme is currently running.
  • Theme switching is easily done via attributes like data-theme on the html tag.
  • A small script should be used in the document head to prevent incorrect theme flashing issues when loading web pages.

Developing a Dark Mode often starts with a seemingly simple idea at first: creating two separate stylesheet files, such as styles.css for the light theme and dark.css for the dark theme. For small interfaces, this approach may seem reasonable and problem-free in the short term.

However, as the application grows, both files begin to act as two separate simulations of the exact same UI set. This makes rules in the dark.css file easy to forget, and every time the main screen is updated, developers must continuously write override code in the dark mode file. As a result, implementing Dark Mode incurs a higher cost because the theme design is embedded at the component level.

Separating CSS files into two theme sets from the beginning is often a trap many developers fall into, thinking it will make management easier. In reality, it creates massive technical debt, as synchronizing various states between the two files becomes highly error-prone and time-consuming to maintain as the system scales. The concept of Tokens solves this by decoupling the UI structure from the color data set.

A better approach is to write components using Semantic Tokens instead of hardcoded color values. Components only care about the semantic role of those values—for example, using the variable --color-surface for cards, input windows, and other surfaces—while the theme determines what those values should render as in each respective mode.

frontend code architecture

This architectural difference is very clear when comparing the old structure, which requires separating the CSS of cards, buttons, and inputs into light and dark versions, with the new structure that features only one set of card, button, and input components while swapping out the light and dark token values instead, as shown in the example structure:

  • Old structure: Light card CSS, Dark card CSS, Light button CSS, Dark button CSS, Light input CSS, Dark input CSS
  • New structure: One card component, One button component, One input component combined with Light token values and Dark token values

For implementing themes in practice, a practical approach is to use a Data Attribute on the HTML tag, such as <html data-theme="dark">, and let CSS handle the scope of token values according to that data set. Modes can then be easily switched via JavaScript, such as setting document.documentElement.dataset.theme = "dark" or removing the attribute to let the operating system manage the default value.

Source: Dev.to

Comments

Leave a Comment
0/2000

Found something wrong in this article? Report an issue with this article