CodeMIRAI
0 XP

Custom properties (variables)

2 min read 4 runnable examples Quiz included

A custom property, usually called a CSS variable, stores a value under a name that starts with --. The var() function reads it:

HTML
<style>
  :root {
    --brand: #5a48f5;
    --radius: 10px;
    --space: 14px;
  }
  body { font-family: system-ui; }
  .btn  { padding: calc(var(--space) * .7) var(--space); border: 0; border-radius: var(--radius);
          background: var(--brand); color: white; font-weight: 600; }
  .card { margin-top: var(--space); padding: var(--space); border: 2px solid var(--brand); border-radius: var(--radius); }
</style>
<button class="btn">Button</button>
<div class="card">Change <code>--brand</code> once in <code>:root</code>, and every use of it updates.</div>

:root is the <html> element, so variables declared there are available everywhere. Press Edit, change --brand to #e0446a and run it again.

Fallbacks

CSS
color: var(--accent, #0aa9cf);   /* #0aa9cf if --accent isn't set */

Overriding for part of the page

Custom properties are inherited, like color, and any element can set its own value for itself and its children:

HTML
<style>
  :root { --tone: #5a48f5; }
  body { display: flex; flex-wrap: wrap; gap: 12px; font-family: system-ui; }
  .card { width: 150px; padding: 14px; border-radius: 10px; border-top: 6px solid var(--tone); background: #f8f8fb; }
  .card h3 { margin: 0 0 6px; color: var(--tone); }
  .card button { padding: 6px 12px; border: 0; border-radius: 6px; background: var(--tone); color: white; }
  .python { --tone: #2f7ccf; }
  .sql    { --tone: #0f9d76; }
  .react  { --tone: #0aa9cf; }
</style>
<div class="card"><h3>Default</h3><button>Start</button></div>
<div class="card python"><h3>Python</h3><button>Start</button></div>
<div class="card sql"><h3>SQL</h3><button>Start</button></div>
<div class="card react"><h3>React</h3><button>Start</button></div>

One set of rules gives four colour schemes, because each card changes only --tone. CodeMIRAI's own course cards work this way: each one sets a single colour variable, and every tint on the card is worked out from it.

Light and dark themes

HTML
<style>
  :root { --bg: #ffffff; --text: #16181d; --muted: #5d6270; --surface: #f3f4f8; --accent: #5a48f5; }
  .dark { --bg: #0f1117; --text: #e9ecf5; --muted: #9aa1b2; --surface: #1a1d27; --accent: #8577ff; }
  body { margin: 0; }
  .app { padding: 18px; background: var(--bg); color: var(--text); font-family: system-ui;
         transition: background-color .3s, color .3s; }
  .app p { color: var(--muted); }
  .panel { padding: 14px; border-radius: 10px; background: var(--surface); }
  .app button { padding: 8px 14px; border: 0; border-radius: 8px; background: var(--accent); color: white; }
</style>
<div class="app" id="app">
  <h2>Theme switching</h2>
  <div class="panel"><p>Every colour on this panel comes from a variable.</p></div>
  <p><button id="toggle">Toggle dark mode</button></p>
</div>
<script>
  document.querySelector("#toggle").addEventListener("click", () => {
    document.querySelector("#app").classList.toggle("dark");
  });
</script>

The components never name a colour directly, only variables, so switching themes just swaps the variables' values.

Changing variables from JavaScript

HTML
<style>
  :root { --hue: 250; --size: 80px; }
  body { font-family: system-ui; }
  .blob { width: var(--size); height: var(--size); margin: 14px 0; border-radius: 30%;
          background: hsl(var(--hue) 80% 60%); transition: all .2s; }
</style>
<label>Hue <input type="range" min="0" max="360" value="250" id="hue"></label>
<label>Size <input type="range" min="40" max="160" value="80" id="size"></label>
<div class="blob"></div>
<script>
  const root = document.documentElement;
  document.querySelector("#hue").addEventListener("input", (e) => root.style.setProperty("--hue", e.target.value));
  document.querySelector("#size").addEventListener("input", (e) => root.style.setProperty("--size", e.target.value + "px"));
</script>

style.setProperty("--name", value) changes a variable, and every rule that uses it updates at once.

Finished this lesson?Mark it complete to earn +20 XP and move your progress on.