Frontend Development 10 min read

Automating Dark‑Mode Color Variable Replacement with Stylelint and PostCSS in Semi Design

This article explains how to automatically replace literal color values with Semi Design CSS variables for dark‑mode support by parsing style files with PostCSS, calculating color similarity with chroma‑js, and applying a custom Stylelint rule that can lint and autofix the code.

ByteFE
ByteFE
ByteFE
Automating Dark‑Mode Color Variable Replacement with Stylelint and PostCSS in Semi Design

Demand & Current Situation

Dark‑mode has become a standard feature for modern web applications. Implementing it requires switching color values based on a theme attribute, which can be done with CSS custom properties. However, existing projects contain many hard‑coded color literals that must be replaced with Semi Design variables, a tedious manual task.

Solution Overview

The approach focuses on two problems: (1) detecting color literals in CSS/SCSS/Stylus files, and (2) determining whether a literal can be substituted by a matching Semi variable. The second step uses chroma‑js to compare color similarity.

PostCSS

PostCSS is a tool for transforming styles with JS plugins. It parses CSS into an AST and provides an API for analysis and transformation.

By leveraging PostCSS, we can walk the AST of any stylesheet (including Sass, Less, Stylus, JSX) and extract color values expressed as keywords, hex codes, or functional notations (rgb, rgba, hsl, etc.). The detection algorithm checks for:

Presence of a known color keyword.

Values starting with “#” for hex colors.

Functions such as rgb , rgba , hsl , hsla , etc.

Once identified, the colors are compared against the Semi Design palette using chroma.distance to decide if a replacement is appropriate.

Stylelint

A modern linter that helps you avoid errors and enforce conventions in your styles.

Stylelint builds on PostCSS and can enforce rules across CSS, Sass, Less, and Stylus. By creating a custom rule ( semi/color-no-literal ) we can flag literal colors and, with the --fix option, automatically replace them with the corresponding var(--color‑…) variables.

Advantages of using Stylelint over a raw PostCSS script include:

No need to manage parsers for different style languages.

Focus solely on analysis and transformation of the AST.

Built‑in CLI and VS Code integration for real‑time feedback.

Final Capability & Usage

Combined with Stylelint you can achieve one‑click find‑and‑replace of all color variables.

Step 1: Install npm packages

$ npm i -D stylelint @ies/stylelint-semi

Step 2: Add/modify configuration

Create a .stylelintrc.json in the project root with the following content:

{
  "plugins": ["@ies/stylelint-semi"],
  "rules": {
    "semi/color-no-literal": [true, {"severity": "warning", "fixExact": false}]
  }
}

Step 3: Run the CLI

$ npx stylelint "**/*.scss"

The command scans all .scss files and reports literals such as:

.banner {
  color: white;
  background: #eee;
  border: 1px solid rgb(0,0,0);
}

Step 4: Apply automatic fixes

$ npx stylelint "**/*.scss" --fix

After fixing, the file becomes:

.banner {
  color: var(--color-white);
  background: var(--color-tertiary-light-hover);
  border: 1px solid var(--color-black);
}

Editor Integration

Install the Stylelint VS Code extension; hovering over a color literal shows a suggestion to replace it with the appropriate Semi variable.

Actual Effect

Side‑by‑side screenshots demonstrate the visual difference before and after applying the automated dark‑mode conversion.

Contact & Recruitment

The Semi Design team maintains a design system for ByteDance’s middle‑office products. For questions, email [email protected] . The article also includes a brief recruitment notice inviting developers to join the team.

frontendAutomationCSSPostCSSstylelintdark modeSemi Design
ByteFE
Written by

ByteFE

Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.