← Все статьи

Туториалы

Тёмная тема для любого сайта — 4 подхода на CSS

В твоей операционной системе тёмная тема есть уже годы. Браузер её поддерживает. Большинство приложений её уважают. Потом ты открываешь документацию, блог или интранет 2014 года — и получаешь в лицо стопроцентно белый фон в 23:00. Четыре способа решить это раз и навсегда.

Почему эта проблема существует

Стандарт CSS prefers-color-scheme есть в Chrome с 2019 года и в Safari с 2018-го. Твоя ОС знает твоё предпочтение, браузер его передаёт, сайты должны его уважать. Должны — на практике ~40% сайтов его игнорируют. Причины: легаси-кодовая база, нет бюджета на вторую тему, маркетинг хочет «согласованности бренда», автор просто до этого не дошёл.

Если автор не делает этого за тебя — сделай сам. Четыре способа, в порядке возрастания изящества.

Способ 1 — универсальный фильтр (работает на всём)

Один сниппет, подходит к любому сайту, никакого анализа конкретного CSS не нужно:

html {
  filter: invert(0.92) hue-rotate(180deg);
  background: #1a1a1a;
}

/* Ре-инвертируем изображения, видео и iframe, чтобы они
   выглядели естественно — иначе селфи твоих друзей будут
   с фильтром «зелёная кожа». */
img, video, picture, iframe, svg,
[style*="background-image"] {
  filter: invert(1) hue-rotate(180deg);
}

Трюк: invert(0.92) вместо полного invert(1) даёт более мягкий чёрный, чем резкая замена белого на чёрный — это меньше утомляет глаза. hue-rotate(180deg) корректирует цвета, так что оранжевый остаётся оранжевым (а не становится синим).

Плюсы: работает везде, ноль анализа.
Минусы: тени, градиенты, нежные серые выглядят странно. Некоторые fixed-элементы (sticky-шапка) могут рассинхронизироваться при прокрутке.

Способ 2 — принудительный prefers-color-scheme: dark

Сайты, у которых есть тёмная тема, но они реагируют только на системное предпочтение. А если ты держишь ОС в светлом режиме (потому что проектируешь в Figma), но хочешь документацию GitHub в тёмном? Переопредели matchMedia:

// Принудительный prefers-color-scheme: dark через JS
const dark = window.matchMedia('(prefers-color-scheme: dark)');
Object.defineProperty(dark, 'matches', {
  get: () => true,
  configurable: true,
});

// Уведомляем слушателей (сайты, подключённые через addEventListener)
dark.dispatchEvent(new Event('change'));

Работает на любом сайте, который использует window.matchMedia('(prefers-color-scheme: dark)') для определения — все современные React/Vue-приложения. Не работает на сайтах, которые определяют тему один раз при загрузке (нужно было бы перезагрузить), или на статическом CSS без JS-определения.

Способ 3 — переопределение CSS custom properties

У сайтов, построенных на CSS-переменных (~60% современных веб-приложений), обычно есть токены темы вроде --bg-primary, --text-primary. Открой DevTools, найди имена, переопредели:

/* Пример: Stripe Dashboard, где всё построено на переменных */
:root {
  --color-canvas-default: #0d1117 !important;
  --color-canvas-subtle: #161b22 !important;
  --color-fg-default: #c9d1d9 !important;
  --color-fg-muted: #8b949e !important;
  --color-border-default: #30363d !important;
}

Плюсы: точно, не портит изображения и тени.
Минусы: 5 минут раскопок в DevTools, чтобы найти имена переменных. Сайт должен использовать CSS-переменные (проверь: document.documentElement.style в консоли).

Способ 4 — отдельная тёмная тема для сайта

Для сайтов, на которых ты проводишь часы каждый день — 30 минут на индивидуальную тему стоят того. Выборочное переопределение:

/* Твой типичный корпоративный интранет */
body, .page-content, .sidebar, .top-bar {
  background: #1a1a1a !important;
  color: #e0e0e0 !important;
}

.card, .panel, .modal {
  background: #242424 !important;
  border-color: #333 !important;
}

a, a:visited { color: #58a6ff !important; }
a:hover { color: #79c0ff !important; }

input, textarea, select {
  background: #1a1a1a !important;
  color: #e0e0e0 !important;
  border-color: #444 !important;
}

/* Таблицы — самое критичное для читаемости */
table th { background: #2d2d2d !important; color: #fff !important; }
table tr:nth-child(odd) { background: #1f1f1f !important; }
table tr:nth-child(even) { background: #1a1a1a !important; }

Начни с главных контейнеров (body, page), спускайся к компонентам (card, модальные окна), завершай элементами форм и таблицами. Без !important обычно не выиграешь — у сайта свои стили с более высокой специфичностью.

Частые ловушки

Как подключить это к JustZix

  1. Установи JustZix (2 минуты).
  2. Создай папку под названием «Тёмная тема».
  3. Правило «Тёмная тема везде»: URL-паттерн *, CSS = способ 1. Сделай его неактивным по умолчанию — включай, когда нужно.
  4. Правило для любимого сайта: паттерн https://myapp.com/*, CSS = способ 3 или 4 (с конкретными токенами / селекторами). Всегда активно.
  5. Переключай всю папку одним кликом по плавающей кнопке — светлая/тёмная за один ход.

Что делать дальше

Та же иерархия (универсальное → точное для сайта) действует и в других категориях правил — смотри Примеры и Сценарии применения. Тёмная тема — лишь самый очевидный случай.

Установи JustZix бесплатно и наконец контролируй внешний вид сайтов, на которые смотришь 8 часов в день.

Оцени эту статью

Оценок пока нет — оцени первым.

Попробуй сам

Установи JustZix и вставь любой сниппет из этой статьи. Две минуты от нуля до работающего правила на всех твоих устройствах.

Получить JustZix

Возможности · Как это работает · Примеры · Применение