Theme Color Switching Solutions for Frontend Projects: Hard Coding, SASS Variables, CSS Variables, Filters, and Grayscale
This article compares five practical methods for changing theme colors in frontend applications—hard‑coded global replacements, SASS variable configuration, combined CSS‑variable and data‑theme approach, CSS filter hue‑rotate, and grayscale filter—detailing implementation steps, code snippets, advantages, and drawbacks to help teams choose the most suitable solution.
Solution 1: Hard‑coded Global Replacement
For legacy front‑end libraries that lack a shared style layer, the only way to change the theme is to replace global styles manually, which involves updating forms, buttons, tables, tabs, containers, and icons. An example from an old project required nearly 500 lines of CSS.
Summary: Hard‑coding works for old projects that share the same base library, but it requires a large amount of manual work.
Solution 2: SASS Variable Configuration
The team’s base component library Link‑ui is built on top of Element‑ui , so theme changes can be made by adjusting a small set of SASS variables supplied by designers.
$--color-primary-bold: #1846D1 !default;
$--color-primary: #2664FD !default;
$--color-primary-light: #4D85FD !default;
$--color-primary-light-1: #9AC0FE !default;
$--color-primary-light-2: #C1DBFF !default;
$--color-primary-lighter: #E8F2FF !default;Import the base variables and the library’s style source files:
@import "./common/base_var.scss";
/* change icon font path, required */
$--font-path: '~link-ui-web/lib/theme-chalk/fonts';
@import "~link-ui-web/packages/theme-chalk/src/index";Globally import the variable file in the project:
import
'@/styles/link-variables.scss';To change the theme, simply modify the six primary color variables, e.g., to a red theme:
$--color-primary-bold: #D11824 !default;
$--color-primary: #FD268E !default;
$--color-primary-light: #D44DFD !default;
// $--color-primary-light-1: #9AC0FE !default;
$--color-primary-light-2: #DCC1FF !default;
$--color-primary-lighter: #F1E8FF !default;Summary: When the base library and style architecture are well designed, changing the theme is as simple as updating SASS variables, but each change requires recompilation, limiting runtime configurability.
Solution 3: CSS Variables + SASS Variables + data‑theme
This approach defines three separate theme files (default, orange, red) that set CSS custom properties for colors, backgrounds, and icons. The SASS variables reference these CSS variables, and the active theme is set by adding a data-theme attribute on the root element.
// theme-default.scss
[data-theme=default] {
--color-primary: #516BD9;
--color-primary-bold: #3347B6;
--color-primary-light: #6C85E1;
--color-primary-light-1: #C7D6F7;
--color-primary-light-2: #c2d6ff;
--color-primary-lighter: #EFF4FE;
--main-background: linear-gradient(90deg,#4e68d7, #768ff3);
--user-info-content-background-image: url('../../assets/main/top-user-info-bg.png');
--msg-tip-content-background-image: url('../../assets/main/top-user-info-bg.png');
...
} // theme-orange.scss
[data-theme=orange] {
--color-primary: #FF7335;
--color-primary-bold: #fe9d2e;
--color-primary-light: #FECB5D;
--color-primary-light-1: #FFDE8B;
--color-primary-light-2: #fcdaba;
--color-primary-lighter: #FFF3E8;
--main-background: linear-gradient(90deg,#ff7335 2%, #ffa148 100%);
--user-info-content-background-image: url('../../assets/main/top-user-info-bg-1.png');
--msg-tip-content-background-image: url('../../assets/main/top-user-info-bg-1.png');
...
} // theme-red.scss
[data-theme=red] {
--color-primary: #DF291E;
--color-primary-bold: #F84323;
--color-primary-light: #FB8E71;
--color-primary-light-1: #FCB198;
--color-primary-light-2: #ffd1d1;
--color-primary-lighter: #FFEEEE;
--main-background: linear-gradient(90deg,#df291e 2%, #ff614c 100%);
--user-info-content-background-image: url('../../assets/main/top-user-info-bg-2.png');
--msg-tip-content-background-image: url('../../assets/main/top-user-info-bg-2.png');
...
}Map the CSS variables back to SASS variables so the existing component library can consume them:
$--color-primary-bold: var(--color-primary-bold) !default;
$--color-primary: var(--color-primary) !default;
$--color-primary-light: var(--color-primary-light) !default;
$--color-primary-light-1: var(--color-primary-light-1) !default;
$--color-primary-light-2: var(--color-primary-light-2) !default;
$--color-primary-lighter: var(--color-primary-lighter) !default;Set the default theme in App.vue :
window.document.documentElement.setAttribute('data-theme', 'default');Result screenshots show the theme switching in action.
Summary: This solution offers the most flexible and maintainable approach, though it requires designers to provide multiple theme assets and more initial configuration work.
Solution 4: CSS Filter hue‑rotate()
The CSS filter property can apply hue rotation to change the overall color tone of an element. Example usage:
body {
filter: hue-rotate(45deg);
}Animated GIF demonstrates the effect.
Summary: Near‑zero cost and easy to implement, but it cannot selectively target specific images or colors without extra handling.
Solution 5: Grayscale Filter for Special Periods
Using the grayscale() filter, the entire page can be turned gray. Values range from 0% (original) to 100% (full grayscale):
body {
filter: grayscale(100%);
}Summary: Very low cost; the effect can be toggled via configuration (e.g., start/end dates) for operational convenience without code releases.
Overall Summary
The team has applied all five methods in real projects. For most cases, the recommended solutions are hard‑coding (Solution 1), the CSS‑variable + data‑theme approach (Solution 3), and the grayscale filter (Solution 5). When the visual requirements are modest, the hue‑rotate filter (Solution 4) offers a zero‑cost option, while the standard product line prefers the comprehensive Solution 3.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.