Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
📐 Days 7–12 – Layout & Responsive Design  ·  Day 12

Day 12: CSS Variables, calc(), clamp() & Dark Mode

⏱ 90 min📶 Intermediate🎯 100% self-study
Day 12 / 20

✅ Today you will learn

  • Custom properties (CSS variables) and var()
  • Design tokens: colours, spacing, radius, shadows
  • calc(), min(), max() and clamp() for fluid sizes
  • Dark mode with prefers-color-scheme
  • A theme switch with data-theme

🏢 In the real world

Two days before launch the client says: “Our new logo is maroon, not orange. Change the colour everywhere.” In a site without variables that means hunting 140 hex codes across 6 files. With variables it is one line. Agencies that build many client sites from one template rely completely on this.

Custom properties

HTML + CSS
<style>
:root {                       /* global "design tokens" */
  --brand: #e34f26;
  --brand-dark: #9a3412;
  --radius: 12px;
  --space: 16px;
  --shadow: 0 8px 24px rgb(0 0 0 / 10%);
}
.card { background: white; border-radius: var(--radius); padding: var(--space); box-shadow: var(--shadow); margin-bottom: var(--space); border-top: 4px solid var(--brand); }
.card h3 { color: var(--brand-dark); margin: 0 0 6px; }
.btn { background: var(--brand); color: white; border: 0; padding: 8px 14px; border-radius: calc(var(--radius) / 2); }
.maroon { --brand: #7f1d1d; --brand-dark: #450a0a; }   /* re-theme a section */
</style>

<div class="card"><h3>Diwali Box</h3><p>Uses the global orange brand.</p><button class="btn">Order</button></div>
<div class="card maroon"><h3>Wedding Box</h3><p>Same CSS, maroon theme – only two variables changed.</p><button class="btn">Order</button></div>
▶  Change two variables → a whole section is re-themed
ConceptExampleNote
Declare--brand: #e34f26;Name starts with two dashes; case-sensitive
Usecolor: var(--brand);Read the value
Fallbackvar(--accent, gold)Used if --accent is not defined
Scope:root = global, .card = localVariables inherit like color does
Live updateselement.style.setProperty("--brand", "#7f1d1d")JavaScript can change themes instantly
💡 Name by role, not colour

Call it --brand, --text, --surface – not --orange. When the brand turns maroon, a variable named --orange holding maroon becomes confusing.

calc(), min(), max()

HTML + CSS
<style>
.bar { height: 28px; background: #264de4; color: #fff; padding: 4px 8px; margin: 6px 0; border-radius: 6px; font: 600 12px system-ui; }
.a { width: calc(100% - 120px); }          /* full width minus a 120px sidebar */
.b { width: min(100%, 360px); }           /* never wider than 360px           */
.c { width: max(50%, 220px); }            /* at least 220px                   */
.d { padding-left: calc(var(--i, 0) * 20px); background: #0891b2; }
</style>

<div class="bar a">calc(100% - 120px)</div>
<div class="bar b">min(100%, 360px)</div>
<div class="bar c">max(50%, 220px)</div>
<div class="bar d" style="--i:1">indent level 1</div>
<div class="bar d" style="--i:3">indent level 3 (calc with a variable)</div>
▶  Maths in CSS – mix units freely

clamp(): fluid typography in one line

HTML + CSS
<style>
h1 {
  /* clamp(MIN, PREFERRED, MAX) */
  font-size: clamp(1.6rem, 1rem + 3vw, 3rem);
  line-height: 1.1;
  margin: 0 0 8px;
}
.section { padding: clamp(16px, 4vw, 48px); background: #eef2ff; border-radius: 12px; }
</style>

<div class="section">
  <h1>Fresh mithai since 1985</h1>
  <p>Resize the window: the heading and padding grow smoothly between their limits – no media queries.</p>
</div>
▶  Heading never smaller than 1.6rem or bigger than 3rem
🧠 Why the “1rem + 3vw” part?

Pure vw ignores the user’s zoom and font settings (accessibility issue). Adding a rem part keeps the text responsive to zoom while still scaling with the screen.

Dark mode – automatic and with a switch

HTML + CSS
<style>
:root {
  --bg: #ffffff; --surface: #f1f5f9; --text: #111827; --muted: #6b7280; --brand: #264de4;
}
@media (prefers-color-scheme: dark) {             /* follows the phone setting */
  :root:not([data-theme="light"]) { --bg: #0b1120; --surface: #1e293b; --text: #e5e7eb; --muted: #94a3b8; --brand: #60a5fa; }
}
:root[data-theme="dark"] { --bg: #0b1120; --surface: #1e293b; --text: #e5e7eb; --muted: #94a3b8; --brand: #60a5fa; }
body { background: var(--bg); color: var(--text); transition: background .3s, color .3s; }
.card { background: var(--surface); padding: 14px; border-radius: 12px; }
.card small { color: var(--muted); }
.card a { color: var(--brand); }
.switch { float: right; background: var(--surface); color: var(--text); border: 1px solid var(--muted); border-radius: 99px; padding: 4px 12px; }
</style>

<button class="switch" onclick="var r=document.documentElement; r.dataset.theme = r.dataset.theme==='dark' ? 'light' : 'dark'">🌓 Theme</button>
<div class="card">
  <h3>Order #1042</h3>
  <small>Placed 25 Oct, 10:42</small>
  <p>2 kg kaju katli · ₹1,800 · <a href="#">Track order</a></p>
</div>
▶  Click 🌓 – only variables change, no component CSS is rewritten
  1. 1Define every colour as a variable on :root
  2. 2Use only variables inside components (no raw hex codes)
  3. 3Override the variables in @media (prefers-color-scheme: dark)
  4. 4Also override them for [data-theme="dark"] so a button can force it
  5. 5Save the user’s choice in localStorage (JavaScript course)
Dark mode recipe used by real products

🏅 Job skills unlocked today

✔ Create design tokens with CSS variables✔ Re-theme sections by overriding variables✔ Use calc(), min(), max() and clamp() for fluid sizing✔ Ship automatic and manual dark mode

Practice tasks

🏋️ Practice – do it yourself

Task 1: Create a button set where .btn uses --bg and --fg variables, and .btn.success / .btn.danger only change those two variables.
Show solution
▶  Result
Task 2: Make the h1 fluid with clamp() between 28px and 56px and the section padding between 16px and 64px.
Task 3: Add dark mode to your Day 8 pricing section using variables and prefers-color-scheme.

Quick quiz

🧠 Quick Quiz – test yourself

1. How do you read the variable --brand?
var() function.
2. Where are global variables usually declared?
The root element.
3. clamp(1rem, 4vw, 2rem) never goes…
Min and max limits.
4. Dark mode that follows the phone setting uses…
User preference query.
5. var(--accent, gold) uses gold when…
Fallback value.

Interview corner

💼 Interview Corner

CSS variables vs Sass variables?

Sass variables are replaced at build time and disappear in the output. CSS custom properties exist at runtime: they cascade, inherit, can be scoped to elements, changed in media queries and updated by JavaScript – which is what makes theming and dark mode easy.

How would you implement dark mode?

Define semantic colour tokens on :root, use them everywhere, override them under prefers-color-scheme: dark, allow a manual override via a data-theme attribute set by JS and stored in localStorage, and check contrast in both themes.

Summary

  • --name: value on :root; use with var(--name, fallback).
  • Override variables to re-theme sections or the whole site.
  • calc/min/max/clamp make sizes fluid without media queries.
  • Dark mode = swap token values via prefers-color-scheme and data-theme.
➡️ Next

Day 13: transitions and transforms – smooth hover effects, scaling cards and flipping cards.

Frequently Asked Questions

Do variables work in media queries conditions?
Not in the condition (@media (min-width: var(--x)) does not work), but you can change variable values inside media queries.
Is dark mode just inverted colours?
No. Use dark grey backgrounds (not pure black), slightly lighter brand colours, softer shadows and re-check contrast.
← CSS (20 Days)
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Next topicDay 13: Transitions & Transforms Your progress: 12 / 20 (60%) · Lesson 13 / 20 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free