در این فصل چه میسازی#
خیلی از کاربرها گوشی و کامپیوترشان را روی تمِ تیره گذاشتهاند و انتظار دارند سایتِ تو هم تیره باشد. در این فصل یاد میگیری بفهمی کاربر تمِ روشن خواسته یا تیره، و کلِ صفحه را بینِ این دو جابهجا کنی — با همان custom property هایی که در ترم ۲ ساختی. آخر فصل یک صفحه داری که در سیستمِ روشن، روشن است و در سیستمِ تیره، تیره، و در هر دو رنگهایش خوانا میمانند.

آخر این فصل میتوانی:
- با
prefers-color-schemeبفهمی کاربر تمِ روشن خواسته یا تیره - یک theme بسازی که مقدارِ token هایش در حالتِ تیره عوض میشود
- بگویی چرا وصلهکردنِ تکتکِ رنگها همیشه یکجا را خراب میکند
- با
color-schemeکاری کنی حتی فرمها و اسکرولبارِ مرورگر هم تیره شوند
قبل از شروع#
- از ترم ۲ فصل ۹: custom property و
var()— این فصل تماماً روی همان بنا شده. - از فصل ۲ (همین ترم):
@media—prefers-color-schemeهم یک ویژگیِ@mediaاست، مثلِmin-width. - از ترم ۲ فصل ۵: contrast و اینکه رنگِ متن و پسزمینه باید فاصلهٔ کافی داشته باشند.
مثل همیشه فقط یک مرورگر لازم داری، یا فقط همین آزمایشگاه.
۱. مشکل: رنگهای چسبیده به کد#
فرض کن کارتت رنگهایش را مستقیم و ثابت نوشته:
body {
background-color: #f6edda;
color: #2c2114;
}
.card {
background-color: #ffffff;
}
در حالتِ روشن عالی است. حالا میخواهی dark mode اضافه کنی. مرورگر یک ویژگیِ @media مخصوص دارد که میگوید کاربر تمِ تیره خواسته: prefers-color-scheme: dark. پس سادهترین فکر این است که در آن حالت، پسزمینهها را تیره کنی:
@media (prefers-color-scheme: dark) {
body {
background-color: #14181f;
}
.card {
background-color: #1e2530;
}
}
در آزمایشگاه امتحانش کن (پایینتر میگویم چطور تمِ تیره را روشن کنی). پسزمینهها تیره شدند، ولی نتیجه فاجعه است: تیتر و متن تقریباً ناپدید شدهاند. متن هنوز رنگِ تیرهٔ #2c2114 را دارد، و حالا روی یک کارتِ تیره نشسته — تیره روی تیره. کاربر یک لکهٔ محو میبیند، نه یک جمله.
🔧 اگر کار نکرد: تو فقط پسزمینهها را عوض کردی و رنگِ متن ثابت ماند. حالا باید برگردی و رنگِ
<h1>،<p>، حاشیهها، دکمه و... را هم تکتک وصله بزنی — و هر بار یکی را جا میاندازی، چون رنگها همهجای فایل پخشاند. این دقیقاً همان دردِ «یک رنگ، ده جا» از ترم ۲ است. راهِ حل هم همان است: theme با custom property. بهجای وصلهکردنِ رنگها، پسزمینه و متن را با هم بهعنوان یک جفت تعریف کن تا همیشه با هم عوض شوند و هیچوقت تیره روی تیره نیفتد.
۲. راهِ حل: theme با custom property#
از ترم ۲ یادت هست: token ها را یکجا روی :root تعریف میکنی و همهجا با var() صدایشان میزنی. اینجا یک قدمِ تازه اضافه میکنیم: همان token ها را داخلِ @media (prefers-color-scheme: dark) دوباره تعریف میکنیم، با مقدارِ تیره. خودِ کارت تغییری نمیکند؛ فقط مقدارِ متغیرها عوض میشود.
:root {
--bg: #f6edda;
--card: #ffffff;
--ink: #2c2114;
--line: #d8ccae;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #14181f;
--card: #1e2530;
--ink: #f2f4f8;
--line: #2c3644;
}
}
حالا هرجای CSS بهجای رنگِ ثابت، var(--bg)، var(--ink) و مثلِ اینها را مینویسی. دقت کن که --bg و --ink یک جفتاند: هر بار یکی تیره میشود، دیگری روشن. برای همین دیگر هیچوقت تیره روی تیره نمیافتد — چون هر دو با هم و در یکجا عوض میشوند.
✅ چک کن: تمِ سیستمت را بین روشن و تیره عوض کن (در تنظیماتِ ویندوز، مک یا موبایل؛ یا در DevTools مرورگر، بخشِ Rendering، گزینهٔ Emulate prefers-color-scheme). صفحه با هر تغییر، کامل بین روشن و تیره میرود و در هر دو حالت متن خواناست. یک token را دستکاری کن — مثلاً --bg تیره را به یک سرمهایِ روشنتر ببر — و ببین فقط پسزمینه عوض میشود و بقیه دستنخورده میماند.
💡 نکته: رنگِ تیره را هیچوقت سیاهِ مطلق (
#000000) نگذار و متن را سفیدِ مطلق نکن؛ کنترستِ خیلیشدید چشم را در تاریکی میزند. یک سرمهایِ خیلیتیره برای پسزمینه و یک سفیدِ کمیشکسته برای متن، هم خواناست هم چشمنواز.
۳. color-scheme: به مرورگر خبر بده#
یک تکهٔ آخر ماند. چیزهایی روی صفحه هستند که خودِ مرورگر رنگشان میکند، نه CSSِ تو: کادرِ ورودیها، اسکرولبار، دکمههای پیشفرض. اگر به مرورگر نگویی صفحهات تیره است، اینها روشن میمانند و مثلِ وصلههای سفید روی تمِ تیره میزنند بیرون. یک خط این را حل میکند:
:root {
color-scheme: light dark;
}
color-scheme: light dark یعنی «این صفحه هم روشن را بلد است هم تیره؛ هرکدام که کاربر خواست، عناصرِ بومیات را هم همانطور بکش». برخلافِ --bg، این یک custom property نیست — یک property واقعیِ CSS است، و کارش هماهنگکردنِ همان چیزهایی است که از دستِ تو خارجاند.
✅ چک کن: در تمِ تیره، حالا اسکرولبار و هر ورودیای هم تیرهاند و دیگر لکهٔ سفید نداری. صفحه یکدست است.
۴. کد کاملِ این فصل#
اول index.html:
<!-- index.html -->
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>dark mode</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main class="page">
<article class="card">
<h1>سلام، تاریکی</h1>
<p>این صفحه تمِ سیستمِ تو را میخواند و خودش را روشن یا تیره میکند.</p>
<a class="btn" href="#">شروع</a>
</article>
</main>
</body>
</html>
و styles.css:
/* styles.css */
* {
box-sizing: border-box;
}
/* tem-e roshan: meghdar-e pishfarz-e token-ha */
:root {
color-scheme: light dark;
--bg: #f6edda;
--card: #ffffff;
--ink: #2c2114;
--muted: #6b6150;
--brand: #2a6b93;
--line: #d8ccae;
}
/* tem-e tire: haman token-ha, meghdar-e digar */
@media (prefers-color-scheme: dark) {
:root {
--bg: #14181f;
--card: #1e2530;
--ink: #f2f4f8;
--muted: #aab3c5;
--line: #2c3644;
}
}
body {
margin: 0;
font-family: Tahoma, sans-serif;
background-color: var(--bg);
color: var(--ink);
line-height: 1.9;
}
.page {
padding: 40px 20px;
}
.card {
max-width: 360px;
margin-inline: auto;
padding: 24px;
background-color: var(--card);
border: 1px solid var(--line);
border-radius: 16px;
}
.card h1 {
margin-block: 0 10px;
color: var(--ink);
}
.card p {
margin-block: 0 16px;
color: var(--muted);
}
.btn {
display: inline-block;
padding: 10px 18px;
border-radius: 10px;
background-color: var(--brand);
color: #ffffff;
font-weight: 700;
}

✅ چک کن: صفحهٔ کامل را در هر دو تم ببین. در روشن: کاغذیِ گرم با متنِ تیره. در تیره: سرمهایِ تیره با متنِ روشن. تنها رنگی که ثابت ماند، سفیدِ رویِ دکمه است — چون دکمه در هر دو تم آبیِ پررنگ دارد و سفید رویش خواناست.
🤖 با AI: رنگهای تمِ تیرهات را به دستیار AI ات بده و بپرس «کنترستِ متن روی پسزمینه در حالتِ تیره برای خواندن کافی است؟». این یکی از بهترین کاربردهای AI است — یک بازبینیِ دسترسپذیری. ولی جوابش را دربست نپذیر: همانجا در آزمایشگاه، تمِ تیره را روشن کن و با چشمِ خودت ببین متن راحت خوانده میشود یا نه. عدد مهم است، ولی چشم داورِ آخر است.
واژههای تازهٔ این فصل#
| کلمه | تلفظ به حروف فارسی | یعنی چه |
|---|---|---|
| dark mode | دارک مود | تمِ تیرهٔ صفحه، برای وقتی کاربر سیستمش را تیره گذاشته |
prefers-color-scheme |
پریفِرز کالر اسکیم | ویژگیِ @media که میگوید کاربر تمِ روشن خواسته یا تیره |
color-scheme |
کالر اسکیم | property ای که به مرورگر میگوید صفحه هر دو تم را دارد تا عناصرِ بومی هم هماهنگ شوند |
| token | توکِن | همان custom property های theme؛ رنگ و اندازههایی که یکجا تعریف و همهجا مصرف میشوند |
تمرینها
اول خودت فکر کن یا امتحان کن — بعد اینجا را باز کن.
در فصل بعد#
الان میتوانی به هر صفحه dark mode بدهی. این آخرین مفهومِ تازهٔ ترمِ Responsive بود. فصل بعد فصلِ پروژه است: همهٔ چیزهایی که این ترم ساختی — @media، تصویرِ responsive، تایپوگرافیِ سیال، منوی بازشو و همین dark mode — را در یک صفحهٔ کامل کنارِ هم میگذاری که از موبایل تا دسکتاپ، در روشن و تیره، درست کار کند.
به آخر این فصل رسیدی!
اگر ساختی و جواب داد، این دکمه مال توست.