HTML-код
Для демонстрации темной темы понадобится простой HTML-файл. В раздел head включены CSS-файл styles.css и два файла JavaScript: darkmode.js и project.js.
Мета-параметры — кодировка, вид экрана и заголовок — упоминаются только для заполнения минимального раздела заголовка.
Кнопка переключения на темную тему — darkmode — расположена внутри элемента <header> на тринадцатой строчке.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
<title>Darkmode-Switch</title>
<link rel="stylesheet" href="css/styles.css">
<script src="js/darkmode.js" defer></script>
<script src="js/project.js" defer></script>
</head>
<body>
<header>
<button class="darkmode" title="darkmode switch" aria-hidden="true"></button>
</header>
<main></main>
<footer></footer>
</body>
</html>
CSS-код
В таблице стилей определяется тело (body) в светлом и темном режиме. Также устанавливается дизайн для переключателя темы в статусе lightmode и darkmode (имя класса, ответственного за это — active).

Данный CSS максимально прост.
*{
box-sizing:border-box;
}
body{
font-family:sans-serif;
background-color:#fff;
color:#000;
}
body.darkmode{
background-color:#000;
color:#fff;
}
header .darkmode{
position:absolute;
right:2rem;
top:2rem;
width:4rem;
height:1.5rem;
border-radius:500px;
border:2px solid #888;
background-color:transparent;
cursor:pointer;
appearance:none;
}
header .darkmode::before{
content:'';
position:absolute;
left:4px;
top:50%;
width:1rem;
height:1rem;
background-color:#888;
border-radius:50%;
transform:translateY(-50%);
}
header .darkmode.active::before{
left:auto;
right:4px;
}
Файл project.js
Этот файл используется для инициализации темной темы с помощью функции darkmode_init() — которая будет описана позже — в событии DOMContentLoaded.
document.addEventListener('DOMContentLoaded',function()
{
darkmode_init();
});
Файл darkmode.js
В этом примере от начала и до конца описана функция для переноса поведения темной темы. Вот полный сценарий:
function darkmode_init()
{
let darkmodeSwitch = document.querySelector('header .darkmode');
let darkmodeCookie = {
set:function(key,value,time,path,secure=false)
{
let expires = new Date();
expires.setTime(expires.getTime() + time);
var path = (typeof path !== 'undefined') ? pathValue = 'path=' + path + ';' : '';
var secure = (secure) ? ';secure' : '';
document.cookie = key + '=' + value + ';' + path + 'expires=' + expires.toUTCString() + secure;
},
get:function()
{
let keyValue = document.cookie.match('(^|;) ?darkmode=([^;]*)(;|$)');
return keyValue ? keyValue[2] : null;
},
remove:function()
{
document.cookie = 'darkmode=; Max-Age=0; path=/';
}
};
if(darkmodeCookie.get() == 'true')
{
darkmodeSwitch.classList.add('active');
document.body.classList.add('darkmode');
}
darkmodeSwitch.addEventListener('click', (event) => {
event.preventDefault();
event.target.classList.toggle('active');
document.body.classList.toggle('darkmode');
if(document.body.classList.contains('darkmode'))
{
darkmodeCookie.set('darkmode','true',2628000000,'/',false);
}
else
{
darkmodeCookie.remove();
}
});
}
Теперь рассмотрим процесс в четыре простых шага.
Шаг 1. Ссылка на кнопку
Сначала перехватываем переключатель из DOM.
let darkmodeSwitch = document.querySelector('header .darkmode');
Шаг 2. Функциональность файлов cookie
Объект darkmodeCookie содержит три метода.
set, чтобы задать файл cookie для темной темы.get, чтобы прочитать файл cookie, если он существует.remove, чтобы удалить файл cookie.
let darkmodeCookie = {
set:function(key,value,time,path,secure=false)
{
let expires = new Date();
expires.setTime(expires.getTime() + time);
var path = (typeof path !== 'undefined') ? pathValue = 'path=' + path + ';' : '';
var secure = (secure) ? ';secure' : '';
document.cookie = key + '=' + value + ';' + path + 'expires=' + expires.toUTCString() + secure;
},
get:function()
{
let keyValue = document.cookie.match('(^|;) ?darkmode=([^;]*)(;|$)');
return keyValue ? keyValue[2] : null;
},
remove:function()
{
document.cookie = 'darkmode=; Max-Age=0; path=/';
}
};
Шаг 3. Обработка классов CSS
Метод get объекта darkmodeCookie позволяет проверить, существует ли файл cookie для темной темы. Если да, то добавляем класс active к переключателю и класс darkmode в тело body.
if(darkmodeCookie.get() == 'true')
{
darkmodeSwitch.classList.add('active');
document.body.classList.add('darkmode');
}
Шаг 4. Управление переключателем
Эта часть скрипта добавляет прослушиватель событий к переключателю, чтобы была возможность изменять классы как в самом переключателе, так и в теле страницы.
В шестой строке кода проверяем, есть ли у body класс darkmode после переключения, которое происходит на четвертой строке. Если это так, устанавливаем файл cookie darkmode, срок действия которого в этом примере истекает через один месяц (2 628 000 000 миллисекунд).
Последнему параметру darmodeCookie.set() в восьмой строке должно быть присвоено значение true, если страница зашифрована по протоколу SSL. Для локального тестирования просто установите туда false. Второй параметр — это значение, здесь используется просто true в качестве строки.

Если файл cookie необходимо удалить, поскольку body не содержит класса darkmode, применяется darkmodeCookie.remove().
darkmodeSwitch.addEventListener('click', (event) => {
event.preventDefault();
event.target.classList.toggle('active');
document.body.classList.toggle('darkmode');
if(document.body.classList.contains('darkmode'))
{
darkmodeCookie.set('darkmode','true',2628000000,'/',false);
}
else
{
darkmodeCookie.remove();
}
});
Заключение
С помощью этих простых шагов вы можете сделать сайт более удобным для пользователя. Для большей гибкости и контроля также можно устанавливать класс darkmode в body с помощью PHP, а не JavaScript.
Читайте также:
- Объясняем Z-index: как позиционировать элементы с помощью CSS
- Как сделать темную тему с помощью CSS
- Основы JavaScript: управление DOM элементами (часть 4)
Читайте нас в Telegram, VK и Дзен
Перевод статьи Stephan Romhart: Code a cookie-based darkmode switch in CSS and vanilla JavaScript





