Тёмная тема
Добавил новое руководство по тёмному режиму. Это перевод статьи автора Мохамеда Адхухама. Если интересует, как сделать тёмную тему и переключать со светлой темы на тёмную, читать обязательно.
Не выкладывайте свой код напрямую в комментариях, он отображается некорректно. Воспользуйтесь сервисом cssdeck.com или jsfiddle.net, сохраните код и в комментариях дайте на него ссылку. Так и результат сразу увидят.
Популярные материалы
- Самоучитель HTML4
- Самоучитель CSS
- Как добавить картинку на веб-страницу?
- Спецсимволы
- Структура HTML-кода
- Введение в HTML
- Способы добавления стилей на страницу
- Выравнивание текста
- Якоря
- Позиционирование элементов
- Как добавить иконку сайта в адресную строку браузера?
- Ссылки
Как добавить тёмную тему на страницу
В последние пять лет в интерфейсном дизайне появилось понятие тёмной темы: это когда фон делают тёмным, а текст — светлым. Это полезно в телефонах для энергосбережения и чтения с экрана ночью. Ну и просто красиво.
Сегодня мы добавим на страницу переключатель тёмной и светлой темы с помощью CSS.
Автопереключение тёмной темы
Современные браузеры умеют определять, что на телефоне или компьютере включена тёмная тема. Для этого разработчики используют такой медиазапрос:
@media screen and (prefers-color-scheme: dark) <>
Если на устройстве используется тёмная тема, то CSS выполнит всё, что написано в фигурных скобках. В нашем случае нам нужно сделать тёмный фон и светлый текст:
@media screen and (prefers-color-scheme: dark) < body < background: black; color: white; >>
Добавим этот код в стили на странице, и задача решена: мы получили поддержку тёмной темы. Если в настройках устройства переключить тему обратно на светлую, то сайт тоже получит белый фон.
Ручное переключение темы
Медиазапросы — это хорошо, но иногда нужно поставить принудительный переключатель темы, чтобы не зависеть от настроек устройства. Например, если нужно отладить тёмную тему, когда у вас на компьютере работает светлая тема.
Чтобы не создавать с нуля страницу, поступим так: создадим копию главной страницы нашего учебного сайта и добавим туда переключатель, который заставит тему смениться.
Настраиваем стили
Единственное, что нам нужно добавить в стили — это два класса: для светлой и тёмной темы:
.theme-dark < background: black; color: white; >.theme-light
Первый класс устанавливает чёрный фон и белый цвет текста, а второй, наоборот, — белый фон и чёрный текст. Цвета здесь можно указывать любые и для любых элементов, а мы для простоты остановимся на двух.
Внешне страница никак не поменяется — мы ещё не применили эти стили. Чтобы это сделать, надо поработать с остальными элементами, например добавить id к тегу — по нему мы будем обращаться к содержимому всей страницы:
Добавляем переключатель
Чтобы мы могли менять светлую тему на тёмную и обратно, добавим простой переключатель. Сделаем его в виде абзаца и добавим его сразу после строки поиска:
Вот что здесь происходит:
onclick=»darkLight()» ← говорим, что должно произойти при нажатии: вызываем функцию darkLight();
style=»cursor: help;»> ← меняем внешний вид курсора при наведении на переключатель;
Включить тёмную тему
← текст надписи.
Переключатель появился на странице, но пока ничего не переключает. Исправим это в скрипте.

Пишем скрипт
Мы указали в свойствах переключателя, что при нажатии нужно выполнить функцию darkLight() — значит, нам нужно добавить её в рабочий скрипт.
Чтобы не зависеть от работы других скриптов и не лезть в их код, сделаем новый js-файл dark.js и положим в него такой код:
// на старте тёмная тема не установлена var dark = false; // получаем доступ ко всей странице и к абзацу с переключателем var a = document.body; var p = document.getElementById("select") // эта функция будет срабатывать при нажатии на переключатель function darkLight() < // если тёмная тема не активна if (!dark) < // добавляем класс с тёмной темой ко всей странице a.className = "theme-dark"; // меняем надпись на переключателе p.innerHTML = "Включить светлую тему"; // а если активна — >else < // добавляем класс со светлой темой ко всей странице a.className = "theme-light"; // меняем надпись на переключателе p.innerHTML = "Включить тёмную тему"; >// меняем значение темы на противоположное dark = !dark; >
Последнее, что осталось сделать, — подключить скрипт в конце HTML-страницы:
Теперь у нас появилась поддержка тёмной темы с моментальным переключением:
Что дальше
Этот способ работает только на одной странице, и после перезагрузки тему нужно переключать заново. В следующий раз сделаем апгрейд — научим сайт запоминать настройки и применять их ко всему сайту. А ещё подружим автопереключение с надписью на переключателе.
Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Как сделать тёмную тему на сайте

Без лишних слов создадим простой переключатель для светлой и темной темы с использованием HTML, CSS и JavaScript. Нам понадобятся три файла — index.html , styles.css и script.js .
HTML
Основная разметка страницы — заголовок, абзац текста, список и текст в рамке.
CSS (styles.css):
Здесь задаём цвета для светлой и тёмной темы, а ещё минимальную стилизацию текста и блока с рамкой.
body < font-family: Arial, sans-serif; transition: background-color 0.3s ease; >body.light-theme < background-color: #ffffff; color: #000000; >body.dark-theme < background-color: #121212; color: #ffffff; >.boxed-text
JavaScript (script.js)
Этот код нужен, чтобы переключать тему при нажатии на кнопку:
document.getElementById('themeToggle').addEventListener('click', function() < const currentTheme = document.body.className; if (currentTheme === 'light-theme') < document.body.className = 'dark-theme'; >else < document.body.className = 'light-theme'; >>);
При загрузке страницы по умолчанию будет установлена светлая тема. При нажатии на кнопку «Переключить тему» будет происходить переключение между светлой и темной темой.
Разбираем CSS
Сначала задаём общие стили для всего документа: шрифт и плавную смену фона, чтобы переход между светлой и тёмной темой был мягче.
body < /* Задаем шрифт для текста на всей странице */ font-family: Arial, sans-serif; /* Добавляем плавный переход для изменения цвета фона. Это сделано для того, чтобы при переключении темы фон менялся плавно */ transition: background-color 0.3s ease; >
Определяем стили для светлой темы. У нас очень простой пример, так что будем менять только цвет фона и цвет текста.
body.light-theme < /* Цвет фона для светлой темы — чёрный */ background-color: #ffffff; /* Основной цвет текста для светлой темы — белый*/ color: #000000; >
Стили для тёмной темы — меняются цвет фона и цвет текста.
/* Темная тема */ body.dark-theme < /* Цвет фона для темной темы */ background-color: #121212; /* Основной цвет текста для темной темы */ color: #ffffff; >
Разбираем JS
Здесь вообще без лишних комментариев.
document.getElementById('themeToggle').addEventListener('click', function() < // Этот код будет выполняться при каждом клике на кнопку // Получаем текущий класс, заданный для элемента body (текущую тему) const currentTheme = document.body.className; // Проверяем, является ли текущая тема светлой if (currentTheme === 'light-theme') < // Если да, меняем тему на темную document.body.className = 'dark-theme'; >else < // Если текущая тема не светлая (или отсутствует), устанавливаем светлую тему document.body.className = 'light-theme'; >>);
Вот и всё! Заботьтесь о пользователях и они ответят вам тем же.
«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.
Читать дальше

Новое в 2023 — text-wrap: balance
В 2023 в CSS появилось любопытное свойство text-wrap со значением balance . Оно «уравновешивает» текстовые элементы, чтобы они приятнее выравнивались внутри блока.
Ограничение — текст не длиннее 6 строк, иначе браузеру придётся непросто, и лучше не применять это свойство к body .
Вот пример заголовка c text-wrap: balance и без него.
На момент написания заметки свойство поддерживается во всех больших браузерах, кроме Safari, а на мобильных — только в Chrome, но то ли ещё будет.
- 13 ноября 2023

Знакомство с CSS
После того как мы разобрались с базовой структурой веб-страницы с помощью HTML, пришло время привнести в неё стиль и красоту. В этом нам поможет CSS, что означает Cascading Style Sheets, или «каскадные таблицы стилей».
Что такое CSS?
CSS используется для оформления HTML-страниц. Если HTML — это скелет сайта, то CSS — его одежда. С помощью CSS мы можем задавать цвета, шрифты, отступы, добавлять анимации и многое другое.
Как подключить CSS к HTML
Есть несколько способов использования CSS внутри HTML:
Внутренний CSS: внутри раздела HTML-документа, в теге :
Внешний CSS: создание отдельного CSS-файла и его подключение с помощью элемента :
Инлайновые стили: непосредственно в HTML-элементе, через атрибут style . Но это не очень хороший способ, лучше его не использовать, и вот почему.
Этот текст будет красного цвета.
Основы синтаксиса CSS
CSS состоит из селекторов и объявлений. Селектор указывает, к какому элементу HTML применяется стиль, а объявление состоит из свойства и его значения.
/* Селектор */ p < /* Свойство : Значение; */ color: green; font-size: 14px; >
Работа с цветом и фоном
Одни из самых основных свойств в CSS — это цвет и фон элементов.
color меняет цвет текста:
background-color меняет фоновый цвет элемента:
Типографика и шрифты
CSS позволяет нам контролировать шрифты на странице:
- font-family задаёт шрифт текста, даже если он нестандартный.
- font-size определяет размер текста.
- font-weight устанавливает жирность шрифта.
Блочная модель
Важной концепцией в CSS является блочная модель, которая включает в себя margin , border , padding , и content .
Внутренние и внешние отступы одной картинкой:
Позиционирование и Flexbox
Чтобы разместить элементы на странице, мы используем различные стратегии позиционирования, включая флексбоксы, которые позволяют нам упростить многие задачи.
.container < display: flex; /* Применяем Flexbox */ justify-content: center; /* Центрирование содержимого по горизонтали */ align-items: center; /* Центрирование содержимого по вертикали */ >
Адаптивный дизайн
С помощью медиа-запросов мы можем создавать адаптивный дизайн, чтобы наш сайт хорошо выглядел на разных устройствах.
@media (max-width: 600px) < .container < flex-direction: column; >>
Это только начало пути в мир CSS, но зная эти основы, вы уже можете начать экспериментировать и применять стили к вашим веб-страницам. В следующей статье мы разберём JavaScript и увидим, как добавить интерактивность нашим веб-страницам. Удачи в творчестве и до новых встреч в коде!
- 1 ноября 2023

Увеличение ссылки при наведении
Задача: плавно увеличить ссылку при наведении.
Решение:
a < display: inline-block; transition: transform 0.3s ease; >a:hover
Первые два свойства просто немного меняют вид ссылки. Свойство color: maroon; меняет цвет текста в тегах на темно-красный, а свойство text-decoration : none; убирает подчеркивание.
Но наша задача — плавно увеличить размер ссылки, а не просто её перекрасить. Поэтому используем свойство transform: scale(1.2) , которое срабатывает при наведении курсора и увеличивает размер ссылки в 1.2 раза по сравнению с её начальным размером.
- 13 октября 2023

WOFF больше не нужен
Я купил и скачал шрифты для недавнего проекта, распаковал папку, где были только WOFF2-файлы, и сначала не поверил, что такое бывает.
Потом мне стало интересно: они что, забыли WOFF? А он вообще ещё нужен? Ну, всё-таки, веб — это место, где постоянно всё меняется и улучшается, поэтому я пошёл и спросил людей в Mastodon. Ответ был единодушным: нужен только WOFF2!
Я хорошо помню пост от Зака в конце 2016, после которого я отказался от исчерпывающего синтаксиса @font-face , включавшего, вдобавок, TTF, EOT и SVG-шрифты, и перешёл только на WOFF2 и WOFF.
Похоже, с тех пор мир веб-шрифтов изменился ещё разок, и вот актуальная версия @font-face :
@font-face
Остался всего один формат. Просто, скажите?
Как писал Зак, «так как в вебе, когда шрифт не найден, всё равно подгружаются системные шрифты, мы можем идти в ногу со временем». Итак, какие браузеры отправятся в тёмные века системных шрифтов с этим синтаксисом?
- IE 11, 10, 9, 8, 7, …
- Chrome 4–35
- Edge 12 и 13
- Safari 3–9.1
- Firefox 2–38
- Opera 22 и ниже
- Android 4.4.4 KitKat и ниже (а это
- Safari на iOS 3.2–9.3
Caniuse.com показывает, что почти у 95% пользователей есть браузер с поддержкой WOFF2. А в относительной статистике (Date Relative — прим. перев.) заметно, что массовый переход на WOFF2 случился в 2015 и 2016. К концу 2016 во всех последних версиях больших браузеров появилась поддержка WOFF2.3
А спустя 7 лет поддержка расширилась настолько, что можно уже не добавлять в проект WOFF-файлы — ну, кроме случая, когда вы точно знаете, что много ваших пользователей используют старые устройства и браузеры.
С другой стороны, нет смысла и удалять WOFF из старых проектов. Если вы подключали WOFF2 раньше WOFF внутри @font-face — и порядок здесь важен — то браузер просто скачает и подключит WOFF2-версию.
И если однажды вы, как и я, обнаружите себя перед папкой, полной файлов WOFF2, знайте, что WOFF — уже всё.
- 23 сентября 2023

Трясём пароль с помощью CSS
Знаете момент, когда всё на сайте уже сделано, и хочется добавить какую-нибудь маленькую незаметную фишку? Мы тоже знаем, поэтому давайте просто потрясём поле пароля, когда пользователь ввёл неверный пароль. Как на Маке.
Вот что получится в итоге:
- 7 сентября 2023

4 способа центрировать текст в CSS
Центрирование элементов на веб-странице — это одна из наиболее распространенных задач, с которой мы сталкиваемся при работе с макетами. И хотя центрирование текста по горизонтали довольно простое ( text-align: center; и делов-то), вертикальное центрирование может быть немного сложнее. Давайте рассмотрим несколько методов.
Метод 1: Flexbox
Flexbox — это один из самых простых и эффективных способов центрирования.
Заворачиваем текст в с классом center-both :
Центрированный текст
.center-both
Метод 2: CSS Grid
HTML такой же, как в предыдущем примере. В CSS включаем гриды и используем свойство place-items со значением center :
.center-both
Метод 3: позиционирование и Transform
Этот метод немного старомодный и работает не идеально. Здесь у div устанавливается relative позиция. А
внутри дива мы сдвигаем с помощью абсолютного позиционирования. Не слишком элегантно:
.center-both < position: relative; >.center-both p
HTML остается таким же. Вот что получается:
Плохой метод: использование line-height
Если у вас однострочный текст, вы можете установить line-height , равный высоте родительского элемента.
.center-both < line-height: 200px; /* Пример высоты */ text-align: center; >
Этот метод не подойдет для многострочного текста. Да и вообще мы очень не рекомендуем так делать, это прям совсем для любителей острых ощущений. Потому что вот:
Если вам интересно узнать больше о каждом из этих методов, рекомендуем посмотреть документацию по Flexbox на MDN или документацию по CSS Grid на MDN, а ещё пройти курсы в HTML Academy.
- 28 августа 2023

Как скруглить рамку. CSS-свойство border-radius
CSS-свойство border-radius помогает скруглить углы элемента. Оно особенно полезно для стилизации кнопок, форм, карточек товаров и других элементов сайта.
- 28 июля 2023

CSS-свойство contain
Представьте, что у вас есть контейнер. Внутри него находятся разные элементы: текст, изображения или что-то другое. Свойство contain говорит браузеру, как именно элементы должны взаимодействовать. Например, они могут быть ограничены, влиять на расположение друг друга или менять свои размеры.
Также свойство помогает повысить производительность страницы. Например, браузер понимает, когда при изменении свойств элемента нужно перерисовать страницу, а когда нет.
⭐ CSS-свойство contain определяет, как элемент должен взаимодействовать с другими элементами внутри контейнера.
Синтаксис
.container
- 14 июля 2023

Как задать позицию и размер элемента. CSS-свойство inset
CSS-свойство inset задаёт позицию и размер элемента на странице. Это комбинация четырёх отдельных свойств: top , right , bottom и left , которые определяют отступы от верхнего, правого, нижнего и левого края элемента.
Синтаксис
.element
- 13 июля 2023

Как перекрыть один элемент другим. CSS-свойство z-index
z-index определяет порядок наложения элементов в трёхмерном пространстве на веб-странице. Свойство управляет тем, как элементы перекрывают друг друга, если они имеют позиционирование, отличное от значения static .
Синтаксис
.my-element
- 10 июля 2023
Подробное руководство по темному режиму на сайте

Темный режим в последнее время приобрел большую популярность. Так, например, компания Apple добавила темный режим в свои операционные системы iOS и macOS. Windows и Google сделали то же самое.
Давайте же взглянем на темный режим в контексте веб-сайтов. Мы рассмотрим различные подходы к реализации дизайна темного режима и технические соображения, которые они влекут за собой. Также, в процессе нашего обсуждения, будут описаны некоторые приемы, которые могут оказаться полезными и в вашей практике.
Переключение между темами
Согласно типичному сценарию на сайте уже есть светлая тема, и вы хотите создать ее более темный аналог. Или, если вы начинаете с нуля, у вас будут две темы: светлая и темная. Одна тема должна быть определена как тема по умолчанию, которую пользователи получают при первом посещении. В большинстве случаев это светлая тема (хотя, как мы увидим в дальнейшем, можно позволить браузеру пользователя сделать этот выбор за нас). Также должен быть способ переключиться на другую тему (что может делаться автоматически) — например, пользователь нажимает кнопку, и цветовая тема меняется.
Для этого существует несколько подходов.
Использование специального класса в теге body
Данный прием заключается в том, что в теге body динамически меняется класс, который используется как зацепка для изменения стилей на странице.
Пример кода JavaScript, который будет менять класс при нажатии на специальную кнопку:
// Находим нужную кнопку const btn = document.querySelector('.btn-toggle'); // Прослушиваем нажатие на кнопку btn.addEventListener('click', function() < // Переключаем (добавляем/удаляем) класс .dark-theme document.body.classList.toggle('dark-theme'); >)
Вот как можно использовать эту идею:
Привет! Это заголовок
Это просто текст, нужный для создания абзаца
А это еще один кусочек текста, потому что два лучше, чем один
Я ссылка.
Общая идея данного подхода состоит в том, что мы оформляем стили как обычно (это будет режим по умолчанию), а затем создаем набор цветовых стилей, опираясь на класс в теге body , которые будут использоваться в качестве темного режима.
Допустим, по умолчанию мы используем светлую цветовую гамму. Все эти светлые стили написаны точно так же, как вы обычно пишете CSS. Учитывая наш HTML код, давайте применим некоторый глобальный стиль к тегу body и ссылкам.
body < color: #222; background: #fff; >a
У нас есть темный текст (#222) и темные ссылки (#0033cc) на светлом фоне (#fff). Наша тема «по умолчанию» успешно стартовала.
Теперь давайте переопределим значения этих свойств, опираясь на другой класс элемента body :
body < color: #222; background: #fff; >a < color: #0033cc; >/* Стили "темного" режима */ body.dark-theme < color: #eee; background: #121212; >body.dark-theme a
Стили темной темы будут производными от одного и того же родительского класса — в нашем примере это класс .dark-theme, который мы установили для элемента body .
Как же будут «переключаться» классы в элементе body , чтобы задействовать темные стили? Для этого мы будем использовать JavaScript! Мы по классу выберем кнопку переключения стилей (.btn-toggle), прикрепим к ней перехватчик событий, который будет перехватывать нажатия на нее, и по этому событию будем добавлять класс темной темы (.dark-theme) в список классов элемента body . Благодаря спецификации каскадной таблицы стилей, это будет переопределять все светлые цвета, которые мы задали по умолчанию.
Вот работающий пример. Нажмите на кнопку, чтобы включить/выключить темный режим:
Использование отдельных таблиц стилей
Вместо того, чтобы объединять все стили в одном файле, мы можем переключаться между таблицами стилей для каждой темы. Для этого нужно, чтобы у нас были полностью готовые таблицы стилей.
Например, стили светлой темы по умолчанию в файле light-theme.css:
/* light-theme.css */ body < color: #222; background: #fff; >a
Затем мы создаем отдельные стили для темной темы и сохраняем их в отдельном файле dark-theme.css:
/* dark-theme.css */ body < color: #eee; background: #121212; >body a
В результате мы получаем две отдельные таблицы стилей — по одной для каждой темы — которые мы можем подключать в HTML разделе . Cначала мы подключим стили светлой темы, так как мы используем их по умолчанию.
Мы используем идентификатор #theme-link, который выбираем при помощи JavaScript, чтобы переключаться между светлым и темным режимами. Только на этот раз мы переключаем файлы таблиц стилей вместо классов.
// Выбираем кнопку const btn = document.querySelector(".btn-toggle"); // Выбираем элемент link со стилями темы const theme = document.querySelector("#theme-link"); // Ловим нажатие на кнопку btn.addEventListener("click", function() < // Если в URL "ligh-theme.css" if (theme.getAttribute("href") == "light-theme.css") < // . переключаем на "dark-theme.css" theme.href = "dark-theme.css"; // Иначе. >else < // . переключаем на "light-theme.css" theme.href = "light-theme.css"; >>);
Использование пользовательских свойств
Мы также можем использовать возможности пользовательских свойств CSS для создания темной темы! Это позволит избежать необходимости писать отдельные наборы правил стилей для каждой темы, что значительно ускорит само написание стилей и значительно облегчает внесение изменений в тему, если это будет необходимо.
Здесь мы также будем использовать способ с заменой класса в теге body и использовать этот класс для перенастройки пользовательских свойств:
// Находим нужную кнопку const btn = document.querySelector('.btn-toggle'); // Прослушиваем нажатие на кнопку btn.addEventListener('click', function() < // Переключаем (добавляем/удаляем) класс .dark-theme document.body.classList.toggle('dark-theme'); >)
Сначала давайте определим значения по умолчанию для светлой темы как пользовательские свойства элемента body :
body
Теперь мы можем переопределить эти значения в классе .dark-theme так же, как мы делали это в первом методе:
body.dark-theme
Вот наши стили с использованием пользовательских свойств:
body < color: var(--text-color); background: var(--bkg-color); >a
Кстати, с таким же успехом мы могли бы определить наши пользовательские свойства внутри псевдосвойства :root , которое указывает на корень документа. Это абсолютно законная и даже обычная практика. В этом случае все стили по умолчанию определяются внутри :root < >, а все стили темной темы определяются внутри :root.dark-mode < >.
Использование серверных скриптов
Если есть возможность работать с серверным языком, скажем PHP, то для наших целей можно использовать его вместо JavaScript. Этот вариант отлично подходит, если вы предпочитаете работать непосредственно в разметке.
$themeToggle = ($themeClass == 'dark-theme') ? 'light' : 'dark'; ?> ">Вкл/Выкл темный режим
Мы можем использовать запрос GET или POST, получаемый от пользователя. После этого, код (в данном случае на PHP) при перезагрузке страницы применяет соответствующий класс в элементе body . В нашем примере мы используем запрос GET (параметры URL).
И конечно же мы можем переключать таблицы стилей.
$themeToggle = ($themeStyleSheet == 'dark-theme.css') ? 'light' : 'dark'; ?> " rel="stylesheet"> ">Вкл/Выкл темный режим
У данного метода есть очевидный недостаток: чтобы переключение вступило в силу необходимо обновить страницу. Но, как мы увидим позже, подобное серверное решение полезно для сохранения выбора пользователя.
Какой метод выбрать?
Выбор «правильного» метода зависит от требований вашего проекта. Например, если вы работаете над крупным проектом, то вы можете использовать метод со свойствами CSS, чтобы было легче иметь дело с большими объемами кода. С другой стороны, если вашему проекту необходимо реализовать поддержку устаревших браузеров, то, возможно, вам придется обратить внимание на другой подход.
Более того, ничто не заставляет нас использовать только один метод. Иногда комбинация нескольких методов может оказаться более эффективным подходом. Также, возможны и другие методы, о которых мы здесь не сказали.
Темный режим на уровне операционной системы
До сих пор мы использовали кнопку для переключения между светлым и темным режимами, но мы можем просто позволить операционной системе пользователя сделать это за нас. Например, многие операционные системы позволяют пользователям выбирать между светлыми и темными темами непосредственно в системных настройках.
Чистый CSS
В CSS есть медиа-запрос prefers-color-scheme , который можно использовать для определения предпочтений системной цветовой схемы пользователя. У него может быть три возможных значения: без предпочтений, светлый (light) и темный (dark).
@media (prefers-color-scheme: dark) < /* Стили темной темы */ >@media (prefers-color-scheme: light) < /* Стили светлой темы */ >
Чтобы все заработало, нам нужно поместить стили темной темы внутри медиа-запроса:
@media (prefers-color-scheme: dark) < body < color: #eee; background: #121212; >a < color: #809fff; >>
Теперь, если пользователь включит темный режим в системных настройках, он получит стили темной темы по умолчанию. Нам не нужно прибегать к JavaScript или серверным сценариям, чтобы решить, какой режим использовать. Нам даже кнопка больше не нужна!
JavaScript
Кроме этого, мы также можем использовать JavaScript, чтобы определить предпочтительную цветовую схему пользователя. Это очень похоже на предыдущий метод, только теперь будет использоваться функция matchedMedia() .
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)'); if (prefersDarkScheme.matches) < document.body.classList.add('dark-theme'); >else
Но у метода с JavaScript есть существенный недостаток: скорее всего, на экране мельком мигнет светлая тема сайта, поскольку JavaScript выполняется после CSS — так называемый «эффект мигания неправильной темы». Это может быть неправильно истолковано как баг.
И, конечно, вместо этого мы можем поменять местами таблицы стилей, как мы делали во втором методе. На этот раз мы связываем обе таблицы стилей и используем медиа-запрос, чтобы определить, какая из них применяется.
Переопределение параметров операционной системы
Мы только что рассмотрели, как учитывать общесистемные предпочтения пользователя по цветовой схеме. Но что, если пользователь захочет переопределить системные предпочтения только для сайта? Ведь то, что пользователь предпочитает темный режим для своей ОС, не всегда означает, что он предпочитает его на веб-сайте. Таким образом предоставление способа вручную переопределить цветовой режим, несмотря на системные настройки, является хорошей идеей.
Чтобы показать, как это сделать, воспользуемся подходом с пользовательскими свойствами CSS. Идея состоит в том, чтобы определить пользовательские свойства для обеих тем, как мы делали это раньше, затем мы поместим темные стили внутри медиа-запроса prefers-color-scheme , и там же определим класс .light-theme, который будет использоваться для переопределения свойств темного режима, если пользователь захочет переключиться между двумя режимами.
/* Цвета по умолчанию */ body < --text-color: #222; --bkg-color: #fff; >/* Цвета темной темы */ body.dark-theme < --text-color: #eee; --bkg-color: #121212; >/* Стили для включения темного режима на уровне ОС */ @media (prefers-color-scheme: dark) < /* темная тема по умолчанию */ body < --text-color: #eee; --bkg-color: #121212; >/* Переопределение темной темы светлыми стилями, если пользователь захочет переключиться */ body.light-theme < --text-color: #222; --bkg-color: #fff; >>
Теперь вернемся к нашей проверенной кнопке переключения между светлой и темной темами. В этот раз мы следуем за цветовые предпочтениями операционной системы и предоставляем пользователю вручную переключать темы.
// Слушаем нажатие на кнопку btn.addEventListener("click", function() < // Если в ОС установлен темный режим. if (prefersDarkScheme.matches) < // . применяем класс .light-theme, чтобы переопределить эти стили document.body.classList.toggle("light-theme"); // Иначе. >else < // . применяем класс .dark-theme, чтобы переопределить эти светлые стили document.body.classList.toggle("dark-theme"); >>);
Поддержка браузеров
Медиа-запрос prefers-color-scheme в настоящее время поддерживается всеми основными браузерами, включая Chrome 76+, Firefox 67+, Chrome Android 76+, Safari 12.5+ (13+ на iOS) и интернет-браузером Samsung. Но не поддерживается IE.
Это охватывает 80,85% пользователей.
Операционные системы, которые в настоящее время поддерживают темный режим, включают macOS (Mojave или более поздние версии), iOS (13.0+), Windows (10+) и Android (10+).
Сохранение предпочтений пользователя
То, что мы рассматривали до сих пор, определенно делает свое дело – меняет цветовую схему в зависимости от настроек ОС или по нажатию кнопки. Это здорово, но выбор пользователя не сохраняется, когда он посещает другую страницу сайта, либо перезагружает текущую страницу.
Нам нужно каким-то образом зафиксировать этот выбор, чтобы он последовательно применялся на всем сайте и при последующих посещениях. Для этого мы можем во время переключения темы сохранять выбор пользователя в поле localStorage. Файлы cookie также отлично для этого подходят.
Давайте рассмотрим оба подхода.
Использование локального хранилища localStorage
Для сохранения информации о выбранном пользователем режиме в локальном хранилище localStorage воспользуемся небольшим скриптом JavaScript. Сохранение будет происходить при переключении темы. При этом, когда страница перезагружается, скрипт будет выбирать нужный вариант из localStorage и применять его. Однако стоит сказать, что JavaScript часто выполняется после CSS, поэтому обратной стороной такого подхода может стать так называемый «эффект мигания неправильной темы», о котором мы рассказывали ранее.
// Выбираем кнопку const btn = document.querySelector(".btn-toggle"); // Выбираем настройки темы из localStorage const currentTheme = localStorage.getItem("theme"); // Если текущая тема в localStorage "dark". if (currentTheme == "dark") < // . тогда используем класс .dark-theme document.body.classList.add("dark-theme"); >// Слушаем нажатия на кнопку btn.addEventListener("click", function() < // Переключаем класс .dark-theme при каждом нажатии document.body.classList.toggle("dark-theme"); // По умолчанию в настройках зададим светлую тему let theme = "light"; // Если установлен класс .dark-theme. if (document.body.classList.contains("dark-theme")) < // . тогда в настройках установим темную тему theme = "dark"; >// Сохраняем настройки в хранилище localStorage localStorage.setItem("theme", theme); >);
Использование cookies на PHP
Чтобы избежать «моргания неправильной темы», мы можем использовать серверный скрипт, такой как PHP. Вместо того, чтобы сохранять предпочтения пользователя в хранилище localStorage, мы создадим файл cookie в скрипте на JavaScript и сохраним его у пользователя. Но опять же, реализовать этот подход можно только в том случае, если у вас есть возможность работать с серверным языком.
// Выбираем кнопку const btn = document.querySelector(«.btn-toggle»); // Слушаем нажатия на кнопку btn.addEventListener(«click», function() < // Переключаем класс .dark-theme document.body.classList.toggle("dark-theme"); // По умолчанию зададим светлую тему let theme = "light"; // Если установлен класс .dark-theme. if (document.body.classList.contains("dark-theme")) < // . тогда установим темную тему theme = "dark"; >// Сохраняем выбор в cookie document.cookie = «theme language-php»> ?>
А так можно сделать, используя разные таблицы стилей:
?> " rel="stylesheet" >
Если на вашем сайте есть учетные записи пользователей – вроде места для входа в систему и управления профилями, — то это также отличное место для сохранения настроек темы. Отправьте эти настройки в базу данных, где хранятся данные учетной записи пользователя. Затем, когда пользователь войдет в систему, извлеките настройки темы из базы данных и примените их с помощью PHP (или любого другого серверного сценария).
Для этого существуют различные способы. В нашем примере мы извлекаем настройки темы пользователя из базы данных и сохраняем их в переменной сессии во время входа в систему.
> // Сначала возьмем переменную сессии, если она есть; иначе берем cookie $themeChoice = $_SESSION[‘user_theme’] ?? $_COOKIE[‘theme’] ?? null; $themeClass = »; if ($themeChoice == ‘dark’) < $themeClass = 'dark-theme'; >?>
Здесь мы используем оператор объединения с null (??), чтобы определить, где брать настройки темы — из переменной сессии или из файла cookie. Если пользователь вошел в систему, то берется значение из переменной сессии вместо значения из файла cookie. Если же пользователь не вошел в систему или вышел из системы, то берется значение из файла cookie.
Сведем все вместе!
Давайте объединим все воедино и создадим рабочую демонстрацию, которая:
- автоматически загружает темную или светлую тему в зависимости от настроек системы,
- позволяет пользователю вручную переопределять системные настройки,
- сохраняет настройки пользователя при перезагрузки системы.
Использование JavaScript и локального хранилища
// Выбираем кнопку const btn = document.querySelector(".btn-toggle"); // Проверяем темный режим на уровне OS const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)"); // Получаем пользовательские настройки темы из локального хранилища const currentTheme = localStorage.getItem("theme"); // Если в локальном хранилище темная тема. if (currentTheme == "dark") < // . переключаем класс .dark-mode у элемента body document.body.classList.toggle("dark-mode"); // Иначе, если в локальном хранилище светлая тема. >else if (currentTheme == "light") < // . переключаем класс .light-mode у элемента body document.body.classList.toggle("light-mode"); >// Слушаем нажатия на кнопку btn.addEventListener("click", function() < // Если в настройках OS темная тема и это соответствует нашему классу .dark-mode. if (prefersDarkScheme.matches) < // . тогда переключаем класс .light-mode document.body.classList.toggle("light-mode"); // . но используем .dark-mode, если класс .light-mode уже установлен var theme = document.body.classList.contains("light-mode") ? "light" : "dark"; >else < // Иначе, делаем то же самое, но с .dark-mode document.body.classList.toggle("dark-mode"); var theme = document.body.classList.contains("dark-mode") ? "dark" : "light"; >// Наконец, сохраним настройки в localStorage для последующего использования localStorage.setItem("theme", theme); >);
Использование PHP и cookies
else if ($_COOKIE['theme'] == 'light') < $themeClass = 'light-theme'; >> ?> const btn = document.querySelector(".btn-toggle"); const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)"); btn.addEventListener("click", function() < if (prefersDarkScheme.matches) < document.body.classList.toggle("light-mode"); var theme = document.body.classList.contains("light-mode") ? "light" : "dark"; >else < document.body.classList.toggle("dark-mode"); var theme = document.body.classList.contains("dark-mode") ? "dark" : "light"; >document.cookie = "theme language-css"> /* Применяем фильтр в элементе body */ body.dark-theme img < filter: brightness(.8) contrast(1.2); >/* Или через медиа-запрос */ @media (prefers-color-scheme: dark) < img < filter: brightness(.8) contrast(1.2); >>
То же самое мы можем сделать и через разметку. Для этого можно использовать элемент picture , который будет загружать разные версии изображения:
Недостатком последнего метода является то, что нам требуется предоставить два файла изображения, в то время как в случае с CSS нам приходится иметь дело только с одним файлом. При этом в последнем методе полностью не учитывается, что пользователь может переключать цветовую тему на сайте.
Тени в темном режиме
Реализация теней в темном режиме — довольно сложная задача. Если мы просто инвертируем темную тень, используя светлые цвета, то получим несуразную светлую тень на темном фоне… и это выглядит не очень эстетично.
В темном режиме возможно использовать темную тень, но цвет фона при этом должен быть достаточно «светлым» (например, темно-серым), чтобы обеспечивался достаточный контраст, и тень была действительно заметна.
Можно использовать прозрачность для передачи глубины, при этом области с высокой прозрачностью имеют меньшую глубину. Это означает, что элементы, которые имеют более высокую высоту, должны иметь меньшую прозрачность, чем элементы, которые «ближе» по глубине к фону.

Типографика в темном режиме
Проблема здесь та же, что и в случае с изображениями: мы должны сбалансировать контраст. Будете использовать слишком жирный шрифт, и получите «громкий» текст, при виде которого хотется отойти от экрана. Будете использовать слишком светлый шрифт, и будем напрягать глаза, придвигаясь к экрану, чтобы рассмотреть его поближе.
Баланс находится где-то посередине.
Иконки в темном режиме
Иконки также попадают в эту «сложную» категорию, так как по сути это нечто среднее между текстом и изображениями. Однако, если мы имеем дело с иконками в формате SVG, то мы можем изменить заливку с помощью CSS. С другой стороны, если мы используем иконки из шрифтовых наборов, то вместо этого мы можем просто изменить свойство color .
/* Иконка SVG */ body.dark-theme svg.icon path < fill: #efefef; >/* Шрифтовая иконка (для примера используем Font Awesome) */ body.dark-theme .fa
Многие дизайнерские соображения, которые справедливы для текста, также в целом применимы к иконкам. Например, следует избегать использования глубоких белых цветов и тяжелых контуров.
Цвета темного режима
Чистый белый текст на чистом черном фоне будет выглядеть неприятно. Хитрость здесь в том, чтобы использовать не совсем белый цвет для текста и не совсем черный для фона. Так, например, для фона часто рекомендуется использовать цвет с кодом #121212.
Цветовые палитры темного режима
Мы уже знаем о разнице в использовании не совсем белых и не совсем черных цветов для текста и изображений. Давайте немного остановимся, чтобы разработать полную цветовую палитру.
Большинство вещей сводится к одному — контраст. Отсюда первый совет: прежде чем остановить свой выбор на каком-либо цвете, пропустите его через средства проверки контрастности, чтобы убедиться, что соотношение цветов соответствует рекомендациям WCAG по крайней мере для оценки AA, которая составляет коэффициент контрастности 4,5:1.
Это означает, что, когда мы имеем дело с темным дизайном, ненасыщенные цвета – это наши друзья. Они помогают предотвратить чрезмерно яркие изображения и при этом дают нам достаточно места для создания эффективного коэффициента контрастности.
Далее, следует помнить, что акцентные цвета предназначены для улучшения. Они, скорее всего, будут ярче, чем фоновый цвет темной темы, поэтому использовать их в качестве основного цвета или цвета фона большого контейнера так же неприятно для глаз, как и яркое изображение или насыщенный белый текст.
В темном режиме мы пытаемся достичь баланса контрастов, но при этом стоит помнить, что темный режим — это нечто большее, чем просто черные и серые цвета. Как насчет темно-синего фона с бледно-желтым текстом? Или темно-коричневого и его оттенков? Существует целый спектр темных цветов, и мы можем использовать любую его часть в нашем дизайне.
Вот несколько примеров темных цветов, которые способны справиться с задачей создания темного режима и без черного цвета:
Руководство по темному режиму на сайте Material Design содержит массу полезной информации о лучших методах проектирования темного режима. Определенно стоит ознакомиться с данным ресурсом, чтобы узнать больше о дизайне темного режима. Правда сайт на английском языке.
Темный режим в интернете
YouTube использует метод с переменными CSS. Они определяют все свои цвета в переменных в селекторе html , в то время как цвета темного режима определены в разделе html:not(.style-scope)[dark] . Когда включен темный режим, YouTube добавляет атрибут dark=»true» к тегу html . Это как раз то, что они используют для переопределения переменных, заданных в HTML.

В интернете подход с пользовательскими свойствами CSS, по-видимому, наиболее популярен. Он используется Dropbox Paper, Slack и Facebook.
Simplenote использует метод с заменой классов, при котором все светлые стили являются потомками класса .theme-light, а все темные стили относятся к классу .theme-dark. Когда тема переключается, к тегу body применяется соответствующий класс.

Twitter идет немного дальше и предлагает на выбор несколько тем: «По умолчанию», «Dim» и «Lights out». Тема «Dim» использует темно-синий цвет в качестве фона. При этом в теме «Lights out» используется абсолютно черный цвет.

С темным режимом или без темного режима? Что выбрать?
Существует множество веских доводов в пользу обоих вариантов. Некоторые из этих доводов даже выходят за рамки пользовательского опыта и затрагивают такие вещи, как сроки, бюджет и затрачиваемые ресурсы.
Со всем уважением к доводам против, приведем несколько причин, почему стоит добавить на сайт темный режим:
- Это круто и модно (хотя это не причина сама по себе, чтобы добавлять темный режим на сайт).
- Это повышает доступность, поддерживая пользователей, страдающих от нагрузки на глаза в слишком ярких темах.
- Это позволяет пользователям выбирать наиболее удобный способ потребления контента, предоставляя нам возможность сохранять контроль над внешним видом и восприятием наших материалов.
- Это помогает увеличить время автономной работы для устройств с OLED-экраном, где более яркие цвета потребляют больше энергии.
Темный режим чрезвычайно популярен и, похоже, эта популярность никуда не денется. Вполне возможно, что ваши пользователи, предпочитающие темный режим, будут ожидать, что он также будет и на вашем сайте. И стоит быть к этому готовым.
