CSS Lesson • Custom Properties + Math

Using var() and calc() in CSS

This lesson teaches what var() and calc() do, why they are useful, and how to use them together to set text color as the reverse of the background color.

Beginner Friendly CSS Variables CSS Math Reverse Color Interactive Lab

Lesson Goal

CSS variables help us store reusable values. CSS math helps us calculate new values from existing ones. In this lesson, we will use both to create a background color and then automatically derive a reversed text color.

Memory trick

Store with custom properties. Read with var(). Compute with calc().

Main idea of reverse color

If a channel is 40, its reverse is 255 minus 40, which is 215.

0

Step 0 — Understand var()

We first learn how CSS variables work.

A CSS custom property is a named value. You usually define it in :root. Then you read it using var().
Basic var() Example
:root{
  --brand: #d97706;
}

.button{
  background: var(--brand);
}

Check

The variable stores the value. The var() function reads the value.

1

Step 1 — Understand calc()

Now we learn CSS math.

The calc() function lets CSS do calculations. It can add, subtract, multiply, and divide values in valid CSS expressions.
Basic calc() Example
.box{
  width: calc(100% - 40px);
}

Important rule

Always keep spaces around operators inside calc(). Write calc(255 - 40), not calc(255-40).

2

Step 2 — Why we store RGB channels separately

This is the key to reversing color with CSS math.

CSS cannot easily take a full hex color like #2a78c8 and directly reverse it with pure calc(). A much better method is to store the red, green, and blue channels separately.
Store RGB Channels as Variables
:root{
  --bg-r: 42;
  --bg-g: 120;
  --bg-b: 200;
}
Why this works:
Reverse red = 255 - red
Reverse green = 255 - green
Reverse blue = 255 - blue
3

Step 3 — Build the reverse text color

Now we use var() and calc() together.

We define background channels, then create reverse channels using calc(255 - var(--bg-r)) and the same idea for green and blue.
Reverse Color Formula
:root{
  --bg-r: 42;
  --bg-g: 120;
  --bg-b: 200;

  --reverse-r: calc(255 - var(--bg-r));
  --reverse-g: calc(255 - var(--bg-g));
  --reverse-b: calc(255 - var(--bg-b));
}
Use Background and Reversed Text Color
.card{
  background-color: rgb(var(--bg-r), var(--bg-g), var(--bg-b));
  color: rgb(var(--reverse-r), var(--reverse-g), var(--reverse-b));
}

Check

Background and text are now mathematically linked. Change the background channels once, and the text color updates automatically.

4

Step 4 — See multiple examples

Here are some cards using the same pattern.

Blue Background Text color is computed as the reverse of the background.
Rust Background Each text channel is 255 minus the background channel.
Green Background Same formula, different values.
Purple Background The whole pattern stays reusable.

Important note

This creates an inverted or reversed RGB color. It is not always the same as the best accessible contrast color, but it is excellent for teaching var() and calc().

Live Reverse Color Lab

Move the sliders to change the background. The text color will update automatically using CSS variables and CSS math.

Interactive RGB Reverse Color Demo

This preview uses exactly the formula taught above.
Red = 40
Green = 120
Blue = 210
Reverse Text Color Preview

Change the sliders. The background and text colors are linked by CSS math.

Generated CSS
:root{
  --bg-r: 40;
  --bg-g: 120;
  --bg-b: 210;

  --reverse-r: calc(255 - var(--bg-r));
  --reverse-g: calc(255 - var(--bg-g));
  --reverse-b: calc(255 - var(--bg-b));
}

.card{
  background: rgb(var(--bg-r), var(--bg-g), var(--bg-b));
  color: rgb(var(--reverse-r), var(--reverse-g), var(--reverse-b));
}

What to observe

  • When red increases, reverse red decreases.
  • When green decreases, reverse green increases.
  • The text color is always computed from the background channels.

Final Build — Complete Single HTML Example

This is the complete final example students can copy into an HTML file and run directly.

Preview idea:
Blue box
auto reverse text
Rust box
auto reverse text
Green box
auto reverse text
Final Complete Code — index.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>Reverse Text Color with var() and calc()</title>

  <style>
    :root{
      --bg-r: 42;
      --bg-g: 120;
      --bg-b: 200;

      --reverse-r: calc(255 - var(--bg-r));
      --reverse-g: calc(255 - var(--bg-g));
      --reverse-b: calc(255 - var(--bg-b));
    }

    *{box-sizing:border-box}

    body{
      margin:0;
      font-family:Arial, sans-serif;
      background:#fff8ef;
      color:#1f2937;
      padding:24px;
    }

    .card{
      max-width:700px;
      margin:40px auto;
      padding:24px;
      border-radius:20px;
      background:rgb(var(--bg-r), var(--bg-g), var(--bg-b));
      color:rgb(var(--reverse-r), var(--reverse-g), var(--reverse-b));
      box-shadow:0 12px 30px rgba(0,0,0,.10);
    }

    h1{
      margin-top:0;
    }
  </style>
</head>
<body>
  <div class="card">
    <h1>Reverse Text Color Demo</h1>
    <p>
      The background color is created from RGB variables.
      The text color is computed using 255 minus each background channel.
    </p>
  </div>
</body>
</html>

Final Check

  • You defined RGB values as CSS variables.
  • You used var() to read those values.
  • You used calc() to compute reversed RGB values.
  • You built a background and text color relationship using only CSS.

Practice Tasks for Students

Basic tasks

  • Create a card with your own RGB background values.
  • Compute reverse text color using the same formula.
  • Make 4 boxes with different backgrounds.
  • Change only the variables, not the card CSS.

Upgrade tasks

  • Use the same RGB variables to style borders and shadows.
  • Build a theme switcher using CSS variables.
  • Add sliders for RGB values and update preview live.
  • Compare reverse color with a manually chosen contrast color.