Post

Css Style To Web App

🎨 Choosing Your CSS Color Strategy: Static Values vs. Dynamic Variables

Most CSS color problems do not start with color theory. They start six months later, when you need to change one shade and realize you hard-coded it in forty places.

That is really what this article is about.

There are two broad ways to handle colors in a web app: the old static approach, where you write values directly into rules, and the dynamic approach, where you define variables once and reuse them everywhere.


1. The “Compiled” Approach: Static Color Values

This is the most traditional way to write CSS. You write the color value, hex, rgb(), hsl(), whatever, directly into the style rule.

When we say this value is “compiled,” we mean it is fixed. Once your CSS is built or loaded by the browser, that color is just sitting there. To change it, you have to find every instance and edit it by hand.

Example: The Static Mess

Imagine you have a primary brand color, #4A90E2. Your CSS might look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* static-colors.css */

.main-header {
  background-color: #4A90E2; /* Our brand color */
  color: #FFFFFF;
}

.primary-button {
  background-color: #4A90E2; /* Our brand color again */
  color: #FFFFFF;
  border: 1px solid #357ABD; /* A darker shade */
}

.sidebar-link:hover {
  color: #4A90E2; /* And again... */
  text-decoration: underline;
}

/* ...and so on, 50 more times... */

The Problems with This Approach

  • 🚫 Poor maintainability: If the brand color changes to #D0021B, you now have to find and replace every instance of #4A90E2. You will miss one eventually. Or replace a different blue you did not mean to touch.
  • 🚫 No theming: Dark mode gets ugly fast. You end up overriding color after color after color.
  • 🚫 Inconsistency: People introduce slight variations like #4a90e2, #4A90E2, or rgb(74, 144, 226). They look the same. Your code does not.

2. The “Runtime” Approach: CSS Variables (Custom Properties)

This is the modern way to handle styling. Instead of hard-coding values, you define a reusable variable in one place. The browser then picks up that variable’s value at runtime, while it is rendering the page.

That means the value can be read, updated, and changed while the user is on the page, without reloading.

Variables are defined using the --variable-name syntax and used with the var() function. The best practice is to define global variables inside the :root selector, which represents the <html> element.

Example: The Dynamic Solution

Here is the same example with CSS variables instead.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/* dynamic-colors.css */

/* 1. Define all our colors in one central place */
:root {
  --color-primary: #4A90E2;
  --color-primary-dark: #357ABD;
  --color-text-light: #FFFFFF;
  --color-text-main: #333333;
}

/* 2. Use the variables throughout the stylesheet */
.main-header {
  background-color: var(--color-primary);
  color: var(--color-text-light);
}

.primary-button {
  background-color: var(--color-primary);
  color: var(--color-text-light);
  border: 1px solid var(--color-primary-dark);
}

.sidebar-link:hover {
  color: var(--color-primary);
  text-decoration: underline;
}

The Benefits of This Approach

  • ✅ Excellent maintainability: If the brand color changes, you change it in one place: :root.
  • ✅ Easy theming: This is the real win. Dark mode becomes a variable override problem instead of a rewrite-the-stylesheet problem.

Let’s see it in action.

✨ Killer Example: Adding Dark Mode

This is where the approach starts paying for itself. You do not touch the component styles. You just provide new values for the variables when a dark-mode class is on the body.

1
2
3
4
5
6
7
8
9
10
11
12
13
/* Add this to the end of your dynamic-colors.css */

body.dark-mode {
  /* Redefine the variables for this context */
  --color-primary: #5AB9EA; /* A lighter blue for dark BG */
  --color-primary-dark: #4A90E2;
  --color-text-light: #121212; /* For light buttons */
  --color-text-main: #EFEFEF; /* Main page text */

  /* We also need to define base styles */
  background-color: #121212;
  color: var(--color-text-main);
}

Now, if you add the class dark-mode to your <body> tag, usually with a little JavaScript, the whole site theme flips. Every component using var() picks up the new values automatically.


3. Comparison and Best Practices

FeatureStatic (“Compiled”) ColorsDynamic (CSS Variables)
MaintainabilityPoor. Requires “find and replace.”Excellent. Edit in one place.
ThemingVery Difficult. Requires overriding every rule.Easy. Redefine variables for a new theme.
Readabilitybackground-color: #4A90E2; (What is this?)background-color: var(--color-primary); (Clear intent.)
JavaScript InteractionNo. Cannot be read or set by JS.Yes. Can be read and changed with JS.
Browser SupportUniversal.Excellent (supported in all modern browsers).

Best Practices for CSS Variables

  1. Be Semantic: Name variables based on their purpose, not their color.

    • Bad: --bright-blue: #4A90E2;
    • Good: --color-primary: #4A90E2;
    • Why? Because in dark mode, --color-primary might become a light blue, and the name --bright-blue would be confusing.
  2. Use Fallbacks: The var() function can take a second parameter: a fallback value to use if the variable isn’t defined.

    • color: var(--color-primary, #333333);
  3. Organize in :root: Keep all your global color variables in the :root pseudo-class at the top of your main stylesheet. This creates a “single source of truth” for your design system.

Conclusion

If you are building a tiny one-page demo, static values are fine. For any real application, use CSS Custom Properties.

The static approach works right up until the day you need to change something across the whole UI. Then it starts charging interest. Variables age much better.

This post is licensed under CC BY 4.0 by the author.