Lesson 38 / الدرس 38

Dark mode / الوضع الداكن

Visitors tell their device whether they want light or dark, and the browser passes that on. With the variables from last lesson, honouring it costs one media query and a second set of values.

يخبر الزوار أجهزتهم إن كانوا يريدون الفاتح أم الداكن، وينقل المتصفح ذلك إليك. ومع المتغيّرات من الدرس الماضي، لا يكلّفك احترام ذلك إلا استعلام وسائط واحدًا ومجموعة قيم ثانية.

Every phone and laptop has a light/dark setting, and it is not a preference about taste. Some people find a bright page painful to read at night; some find a dark one harder in daylight. The browser reports that choice to CSS as a media feature, and this site you are reading right now uses exactly the technique in this lesson.

The feature is prefers-color-scheme, and it takes light or dark. Written on its own it is just another media query, like the width ones in lesson 36 — but it asks about the visitor rather than the window.

Variables make it two blocks, not two stylesheets

The wrong way is to repeat every rule inside the media query. The right way is the one last lesson set up: define your colours once as variables, then redefine only the variables for dark. Every rule in the stylesheet keeps pointing at var(--bg) and never needs to know which mode it is in.

:root {
    --bg: #ffffff;
    --text: #151821;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #0f1117;
        --text: #e6e8ee;
    }
}

body {
    background: var(--bg);
    color: var(--text);
}
Two variables, one media query, and the whole page follows. Add a hundred more rules and none of them changes — this is the payoff for the indirection that variables cost you last lesson.

Dark is not "invert everything"

  • Avoid pure black and pure white. #000 under #fff text is harsh and makes letters look like they are glowing. Near-black and near-white read better.
  • Lighten a surface to raise it, do not add a shadow. Shadows barely show on a dark background; a slightly lighter panel is how depth reads in the dark.
  • Re-check every contrast pair. A colour that passed on white can fail badly on a dark background — a mid grey is the usual casualty.
  • Dim photographs slightly. A bright image on a dark page is a torch in a dark room; filter: brightness(.9) is usually enough.

One line worth adding while you are here: color-scheme: light dark on :root tells the browser your page handles both. It then draws its own parts — form controls, scrollbars, the default page background before your CSS loads — in the matching mode, which is what stops a white flash on a dark-mode phone.

PieceDoes
@media (prefers-color-scheme: dark)Asks what the visitor set on their device
Redefine variables inside itChanges every rule at once, without repeating any
color-scheme: light darkLets the browser theme its own controls and scrollbars
filter: brightness(.9)Stops photos glaring on a dark page

The whole of dark mode, in four lines.

Try it live / جرّب بنفسك

Preview / المعاينة

Check yourself / اختبر نفسك

1. What does prefers-color-scheme ask about?

2. Why redefine variables inside the media query instead of repeating rules?

3. Why avoid pure black behind pure white text in dark mode?

Your task / مهمتك

Take a card and give it a dark mode. Define at least three colours as variables on :root, redefine them inside a prefers-color-scheme: dark query, add color-scheme: light dark, and make sure no rule outside the query mentions a colour directly.

خذ بطاقة وأعطها وضعًا داكنًا. عرّف ثلاثة ألوان على الأقل كمتغيّرات على :root، وأعد تعريفها داخل استعلام prefers-color-scheme: dark، وأضف color-scheme: light dark، وتأكد أن لا قاعدة خارج الاستعلام تذكر لونًا مباشرة.

  • At least three colours are variables on :root ثلاثة ألوان على الأقل متغيّرات على :root
  • A prefers-color-scheme: dark query redefines them استعلام prefers-color-scheme: dark يعيد تعريفها
  • color-scheme: light dark is set تم ضبط color-scheme: light dark
  • No colour literal appears outside :root لا يظهر أي لون صريح خارج :root
How do you want to submit? / كيف تريد التسليم؟