@mochenkow

Как адаптировать темную тему сайта под тему устройства?

На сайт внедрил переключатель темы (темная и светлая)
Как можно сделать, чтобы тема подстраивалась под тему устройства? iOS, Mac Os, Windows?

Вот инструкция, по которой внедрял темную тему:

Создаем index.php

index.php
<!DOCTYPE html>
<html>
    <head>
   	 <title>Site with dark theme</title>
   	 <meta charset="utf-8">
   	 <link rel="stylesheet" type="text/css" href="styles/main.css">
   	 <link rel="stylesheet" type="text/css" href="styles/light.css" id="theme-link">
    </head>
    <body>
   	 <div class="wrapper">
   		 <div class="theme-button" id="theme-button">Change theme</div>
   		 <header class="header">
   			 <div class="header__content">
   				 <h1>Site with dark theme</h1>
   				 <nav class="nav">
   					 <div class="nav__content">
   						 <a href="#" class="nav__item nav__item_active">Home</a>
   						 <a href="#" class="nav__item">Blog</a>
   						 <a href="#" class="nav__item">About</a>
   						 <a href="#" class="nav__item">Contacts</a>
   					 </div>
   				 </nav>
   			 </div>
   		 </header>
   		 <main class="main">
   			 <article class="main__content">
   				 //Тут будет Lorem Ipsum
   			 </article>
   		 </main>
   	 </div>
   	 <script type="text/javascript" src="scripts/themes.js"></script>
    </body>
</html>


Создаем 3 css файла (main.css, light.css, dark.css)

main.css
body, html
{
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
    font-family: arial;
    font-siz: 16px;
}

.wrapper
{
    width: 100%;
}

.header
{
    background: #ccc;
}

.header__content
{
    padding: 5px;
}

.nav__item
{
    display: inline-block;
    vertical-align: middle;
    padding: 15px 25px;
    margin: 2px;
    cursor: pointer;
    text-decoration: none;
}

.main__content
{
    width: 80%;
    margin: 0 auto;
}


.theme-button
{
    position: absolute;
    right: 5px;
    top: 5px;
    display: inline-block;
    padding: 10px 25px;
    cursor: pointer;
}


light.css
{
    background: #f4f4f4;
    color: #111;
}

.header
{
    background: #4a76a8;
    color: #f4f4f4;
}

.nav__item
{
    color: #f4f4f4;
    background: #4a76a8;
}

.nav__item:hover, .nav__item_active
{
    background: #4f7faf;
}

.theme-button
{
    color: #f4f4f4;
    background: #444;
}

.theme-button:hover
{
    background: #555;
}


dark.css
body
{
    background: #111;
    color: #f4f4f4;
}

.header
{
    background: #373737;
    color: #f4f4f4;
}

.nav__item
{
    color: #f4f4f4;
    background: #373737;
}

.nav__item:hover, .nav__item_active
{
    background: #444;
}

.theme-button
{
    color: #f4f4f4;
    background: #4f7faf;
}

.theme-button:hover
{
    background: #6f9fcf;
}


Для смены тем мы напишем функцию ChangeTheme(), которая будет вызываться при нажатии на одноимённую кнопку. Функция будет проверять, какой стиль подключён, а потом менять его на противоположный:

theme.js
var btn = document.getElementById("theme-button");
var link = document.getElementById("theme-link");

btn.addEventListener("click", function () { ChangeTheme(); });

function ChangeTheme()
{
    let lightTheme = "styles/light.css";
    let darkTheme = "styles/dark.css";

    var currTheme = link.getAttribute("href");
    var theme = "";

    if(currTheme == lightTheme)
    {
   	 currTheme = darkTheme;
   	 theme = "dark";
    }
    else
    {    
   	 currTheme = lightTheme;
   	 theme = "light";
    }

    link.setAttribute("href", currTheme);

    Save(theme);
}


В конце вызывается функция Save(), которая будет сохранять тему. Пока можно оставить её пустой и проверить, правильно ли работает скрипт:

Теперь всё работает, но если пользователь обновит страницу, то его тема снова станет светлой. Чтобы это исправить, нам понадобится немного PHP. В самое начало страницы добавьте такой код:

Сверху в index.php
<?php
session_start();

if(!isset($_SESSION["theme"]))
{
    $_SESSION["theme"] = "light";
}
?>


Здесь запускается сессия, а потом проверяется существование элемента theme в супермассиве _SESSION. Если его нет, то он объявляется со значением light — это и есть сохранённая тема, которая хранится в браузере пользователя.

Изменим подключение стиля так, чтобы по умолчанию загружался сохранённый файл:


Меняем в index.php
<link rel="stylesheet" type="text/css" href="styles/<?php echo $_SESSION["theme"]; ?>.css" id="theme-link">


Теперь нужно сделать так, чтобы при смене темы отправлялся запрос другому php-файлу, который и будет менять $_SESSION["theme"]. Начнём с самого файла, который назовём themes.php:

themes.php
<?php
session_start();

if(isset($_GET["theme"]))
{
    $theme = $_GET["theme"];

    if($theme == "light" || $theme == "dark")
    {
   	 $_SESSION["theme"] = $theme;
    }
}
?>


Этот файл получает запрос, а потом, если в запросе содержится параметр theme со значением light или dark, меняет сохранённый стиль.

Остаётся только дописать функцию, которая будет отправлять этот запрос, — ту самую Save():


Добавляем в theme.js
function Save(theme)
{
    var Request = new XMLHttpRequest();
    Request.open("GET", "./themes.php?theme=" + theme, true); //У вас путь может отличаться
    Request.send();
}


Теперь при обновлении страницы тема не будет меняться.
  • Вопрос задан
  • 781 просмотр
Решения вопроса 1
wapster92
@wapster92 Куратор тега JavaScript
Наизобретают каких-то велосипедов без колес https://developer.mozilla.org/en-US/docs/Web/CSS/@... и есть отличная статья на хабре https://habr.com/ru/company/timeweb/blog/523478/
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы