CSS Variables & Custom Properties
CSS ভ্যারিয়েবল ও কাস্টম প্রপার্টি
1. Define a Value Once, Use It Everywhere
Imagine your brand color is used in forty different CSS rules across a site, and the client asks you to change it. Without variables, you'd hunt down and edit forty lines. With a CSS custom property — commonly called a CSS variable — you define the color once and every rule that references it updates automatically. This is the foundation of real, maintainable design systems.
Core insight: a CSS variable lets you define a color once and reuse it site-wide — to change it, you edit only one place.
2. --variable-name Syntax
A custom property name always starts with two dashes: --main-color: #39b549;. It's not a
special keyword — it's any name you choose, prefixed with --. Custom properties are declared
inside a CSS rule just like any other property, most often inside :root, a pseudo-class that
matches the top-level <html> element and makes the variable available everywhere on
the page.
--main-color: #39b549;। এটি কোনো বিশেষ কিওয়ার্ড নয় — -- প্রিফিক্স দিয়ে আপনি নিজের পছন্দমতো যেকোনো নাম দিতে পারেন। Custom property অন্য যেকোনো প্রপার্টির মতোই একটি CSS নিয়মের ভেতরে ঘোষণা করা হয়, সবচেয়ে বেশি ব্যবহৃত হয় :root-এর ভেতরে — যা শীর্ষ-স্তরের <html> এলিমেন্টকে ম্যাচ করে এবং ভ্যারিয়েবলটিকে পুরো পেজের যেকোনো জায়গায় ব্যবহারযোগ্য করে তোলে।
3. var() — Reading a Variable, with Fallbacks
To use a custom property, wrap its name in var(): color: var(--main-color);.
var() also accepts an optional second argument as a fallback:
color: var(--main-color, blue); uses blue if --main-color was never defined or
is invalid. Fallbacks make components safer to reuse in contexts where the variable might not exist yet.
var()-এ মুড়িয়ে নিন: color: var(--main-color);। var() ঐচ্ছিক দ্বিতীয় আর্গুমেন্টও গ্রহণ করে fallback হিসেবে: color: var(--main-color, blue); — --main-color কখনো সংজ্ঞায়িত না হলে বা অবৈধ হলে blue ব্যবহার করবে। Fallback একটি কম্পোনেন্টকে এমন context-এও নিরাপদে পুনর্ব্যবহারযোগ্য করে তোলে যেখানে ভ্যারিয়েবলটি হয়তো এখনো নেই।
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>CSS Variables</title></head>
<body>
<div class="card">
<h2>Design System Card</h2>
<p>All colors and spacing here come from variables defined once on :root.</p>
<button class="btn">Action</button>
</div>
</body>
</html>
:root {
--brand-color: #39b549;
--text-color: #1a1a1a;
--gap: 16px;
}
body { font-family: sans-serif; padding: var(--gap); }
.card {
border: 2px solid var(--brand-color);
border-radius: 8px;
padding: var(--gap);
color: var(--text-color);
}
.btn {
background: var(--brand-color);
color: white;
border: none;
padding: 8px 16px;
border-radius: 6px;
/* fallback in case --highlight-color is never defined */
box-shadow: 0 0 0 2px var(--highlight-color, #e6f4e8);
}
4. Scoping Variables to :root or a Class
Variables declared on :root are global — available anywhere. But you can also declare a
variable inside any regular class, and it will only be available to that element and its descendants,
overriding the global value within that scope. This is exactly how component-level theming
works: a .card can redefine --brand-color just for itself without touching the
site-wide default.
:root-এ ঘোষিত ভ্যারিয়েবল গ্লোবাল — যেকোনো জায়গা থেকে ব্যবহারযোগ্য। কিন্তু আপনি যেকোনো সাধারণ ক্লাসের ভেতরেও ভ্যারিয়েবল ঘোষণা করতে পারেন, যা কেবল সেই এলিমেন্ট ও তার descendant-দের জন্য প্রযোজ্য হবে — সেই scope-এর ভেতরে গ্লোবাল মানকে override করে। কম্পোনেন্ট-লেভেল থিমিং ঠিক এভাবেই কাজ করে — একটি .card নিজের জন্য --brand-color পুনর্সংজ্ঞায়িত করতে পারে, সাইট-ওয়াইড ডিফল্ট স্পর্শ না করেই।
5. Theming & Dark Mode Basics
Because variables can be redefined per-scope, theming becomes a matter of swapping a small set of
values rather than rewriting rules. A typical dark-mode setup defines --bg and
--text on :root for light mode, then redefines the same variable names inside a
.dark-theme class (or a prefers-color-scheme: dark media query). Every rule
that already uses var(--bg) and var(--text) updates automatically — you never
touch those rules again.
:root-এ --bg ও --text সংজ্ঞায়িত করা হয়, তারপর একই ভ্যারিয়েবল নাম .dark-theme ক্লাসের ভেতরে (অথবা prefers-color-scheme: dark মিডিয়া কোয়েরিতে) পুনর্সংজ্ঞায়িত করা হয়। ইতিমধ্যে var(--bg) ও var(--text) ব্যবহার করা প্রতিটি নিয়ম নিজে থেকেই আপডেট হয়ে যায়।
The demo below can't run JavaScript to flip a toggle, so it shows two .card elements side by
side — one scoped to light-mode variables, one scoped to dark-mode variables — to make the effect of
variable scoping visible without any script.
.card এলিমেন্ট পাশাপাশি দেখায় — একটি light-mode ভ্যারিয়েবলের scope-এ, অন্যটি dark-mode ভ্যারিয়েবলের scope-এ — কোনো স্ক্রিপ্ট ছাড়াই variable scoping-এর প্রভাব দৃশ্যমান করার জন্য।
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Theme Demo</title></head>
<body>
<div class="card light-theme">
<h3>Light Card</h3>
<p>Uses the default :root variables.</p>
</div>
<div class="card dark-theme">
<h3>Dark Card</h3>
<p>Same markup, variables re-scoped locally.</p>
</div>
</body>
</html>
:root {
--bg: #ffffff;
--text: #1a1a1a;
--accent: #39b549;
}
body { font-family: sans-serif; display: flex; gap: 16px; }
.card {
background: var(--bg);
color: var(--text);
border: 2px solid var(--accent);
border-radius: 8px;
padding: 16px;
flex: 1;
}
/* Re-scope the same variable names for this element and its children */
.dark-theme {
--bg: #0f172a;
--text: #e2e8f0;
--accent: #4ade80;
}
.dark-theme on
<body> with a few lines of JavaScript — the CSS variable re-scoping shown above is the
entire trick; the JavaScript only flips which class is present.
প্রোডাকশনে আসল dark-mode টগল কেবল
<body>-তে .dark-theme-এর মতো একটি ক্লাস কয়েক লাইন JavaScript দিয়ে যোগ/বাদ দেয় — উপরে দেখানো CSS ভ্যারিয়েবল re-scoping-ই পুরো কৌশল; JavaScript কেবল কোন ক্লাস আছে তা বদলায়।
6. Reference (রেফারেন্স)
| Concept | Meaning | বাংলায় |
|---|---|---|
--name: value; | Declares a custom property. | একটি custom property ঘোষণা করে। |
var(--name) | Reads the value of a custom property. | একটি custom property-এর মান পড়ে। |
var(--name, fallback) | Uses fallback if the variable is undefined. | ভ্যারিয়েবল অসংজ্ঞায়িত হলে fallback ব্যবহার করে। |
:root | Global scope for variables (matches <html>). | ভ্যারিয়েবলের গ্লোবাল scope (<html>-কে ম্যাচ করে)। |
| Class-level redefinition | Overrides a variable only within that element's scope. | কেবল সেই এলিমেন্টের scope-এর ভেতরে ভ্যারিয়েবল override করে। |
7. Practice Problems
Try each problem yourself first, then open the answer and run it in the live preview.
-
Define
--spacing: 20px;on:rootand use it as the padding of a.box.:root-এ--spacing: 20px;সংজ্ঞায়িত করে একটি.box-এর padding হিসেবে ব্যবহার করুন।✨ Show Answer (উত্তর দেখুন)
ans1.html<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Spacing Variable</title></head> <body> <div class="box">Padded box</div> </body> </html>style.css:root { --spacing: 20px; } .box { padding: var(--spacing); background: #e6f4e8; border: 2px solid #39b549; } -
Write a
var()call for--link-colorwith a fallback ofblue.--link-color-এর জন্য একটিvar()কল লিখুন যার fallback হবেblue।✨ Show Answer (উত্তর দেখুন)
Answer:
color: var(--link-color, blue);— if--link-coloris undefined or invalid, the browser falls back to blue.color: var(--link-color, blue);—--link-colorঅসংজ্ঞায়িত বা অবৈধ হলে ব্রাউজার fallback হিসেবে blue ব্যবহার করবে। -
Create two
.cardelements where a second card overrides--accentlocally to a different color while reusing the same rules.দুটি.cardএলিমেন্ট তৈরি করুন যেখানে দ্বিতীয় কার্ডটি একই নিয়ম পুনর্ব্যবহার করেও--accent-কে ভিন্ন রঙে override করে।✨ Show Answer (উত্তর দেখুন)
ans3.html<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Local Override</title></head> <body> <div class="card">Default accent</div> <div class="card purple">Overridden accent</div> </body> </html>style.css:root { --accent: #39b549; } .card { border: 3px solid var(--accent); padding: 12px; margin-bottom: 8px; } .card.purple { --accent: #7c3aed; } -
In one sentence, explain why
:rootis a common place to declare variables.এক বাক্যে ব্যাখ্যা করুন, ভ্যারিয়েবল ঘোষণার জন্য:rootকেন একটি সাধারণ জায়গা।✨ Show Answer (উত্তর দেখুন)
Answer:
:rootmatches the top-level<html>element, so any variable declared there is inherited and available to every other element on the page.:rootশীর্ষ-স্তরের<html>এলিমেন্টকে ম্যাচ করে, তাই সেখানে ঘোষিত যেকোনো ভ্যারিয়েবল inherit হয়ে পেজের প্রতিটি অন্য এলিমেন্টে ব্যবহারযোগ্য হয়ে যায়। -
Build a simple light/dark theme pair of variables (
--bg,--text) and apply them to a.panel, showing both a default and a.darkversion.একটি সাধারণ light/dark থিম ভ্যারিয়েবল জোড়া (--bg,--text) বানিয়ে একটি.panel-এ প্রয়োগ করুন, ডিফল্ট ও.dark— দুটি ভার্সনই দেখান।✨ Show Answer (উত্তর দেখুন)
ans5.html<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Panel Theme</title></head> <body> <div class="panel">Light panel</div> <div class="panel dark">Dark panel</div> </body> </html>style.css:root { --bg: #ffffff; --text: #1a1a1a; } .panel { background: var(--bg); color: var(--text); padding: 14px; margin-bottom: 8px; font-family: sans-serif; } .panel.dark { --bg: #0f172a; --text: #e2e8f0; }
Summary — Module 20
CSS custom properties (--name: value;), read with var(--name) and an optional
fallback, let you define a value once and reuse it everywhere. Scoping a redefinition to :root
makes it global; scoping it to a class makes it local — and that local override is the entire mechanism
behind theming and dark mode.
--name: value;), যা var(--name) ও ঐচ্ছিক fallback দিয়ে পড়া হয়, একটি মান একবার সংজ্ঞায়িত করে সর্বত্র পুনর্ব্যবহার করতে দেয়। :root-এ পুনর্সংজ্ঞা দিলে তা গ্লোবাল হয়; ক্লাসে দিলে তা লোকাল হয় — আর এই লোকাল override-ই থিমিং ও dark mode-এর পুরো প্রক্রিয়া।