Как правильно реализовать смену на тёмную тему?

Ссылка скопирована
31 января 2026 1 ответ

Есть код смены на тёмное оформление, которое задействуется после нажатия соответствующей кнопки. Так-то реализовал через php, могу сделать через javascript. Проблема в том, что нужно также менять метатег.
<meta name="theme-color" content="#ff0000">
как лучше всего это сделать?

через js делал, даже без jquery, но наблюдается проблема мерцания, скрипт срабатывает не сразу и не важно, где его размещать, в начале или в конце, только кеш cms спасает. других вариантов нет? Можно на пхп, сделать, тогда мерцаний не будет.

php

$dark_mode_auto = false; if( preg_match('#auto-dark-mode|#i', $member_id['xfields']) ) {   	$dark_mode_auto = true; }   if( $dark_mode_auto ) {      	$a_hour = langdate( "G", $_TIME );    	if( $a_hour &gt;= 0 AND ($a_hour &gt; 20 OR $a_hour &lt; 6) ) { 		$theme_class = 'darkstyle';   	} else $theme_class = '';   	$tpl-&gt;set_block ( "'\[dark-mode-auto\](.*?)\[/dark-mode-auto\]'si", "" );    } else {        if( isset($_COOKIE['theme-class']) AND $_COOKIE['theme-class'] == 'darkstyle' ) {       $theme_class = totranslit($_COOKIE['theme-class']);       $night_mode = " checked";     } else { $theme_class = ""; $night_mode = ""; }      $tpl-&gt;set ( '{night-mode}', $night_mode );     $tpl-&gt;set( '[dark-mode-auto]', "" );     $tpl-&gt;set( '[/dark-mode-auto]', "" );    }  $tpl-&gt;set ( '{theme-class}', $theme_class );

$dark_mode_auto = false; if( preg_match('#auto-dark-mode|#i', $member_id['xfields']) ) { $dark_mode_auto = true; } if( $dark_mode_auto ) { $a_hour = langdate( "G", $_TIME ); if( $a_hour &gt;= 0 AND ($a_hour &gt; 20 OR $a_hour &lt; 6) ) { $theme_class = 'darkstyle'; } else $theme_class = ''; $tpl-&gt;set_block ( "'\[dark-mode-auto\](.*?)\[/dark-mode-auto\]'si", "" ); } else { if( isset($_COOKIE['theme-class']) AND $_COOKIE['theme-class'] == 'darkstyle' ) { $theme_class = totranslit($_COOKIE['theme-class']); $night_mode = " checked"; } else { $theme_class = ""; $night_mode = ""; } $tpl-&gt;set ( '{night-mode}', $night_mode ); $tpl-&gt;set( '[dark-mode-auto]', "" ); $tpl-&gt;set( '[/dark-mode-auto]', "" ); } $tpl-&gt;set ( '{theme-class}', $theme_class );

js

const mtThemeColor = document.querySelector('meta[name="theme-color"]'); if(document.cookie.includes("theme-class=darkstyle")){ 	mtThemeColor.setAttribute('content', '#1a1e29'); } function changeTheme() { 	setTimeout(function(){	 		if( $('body').hasClass('darkstyle') ) { 			$('body').removeClass('darkstyle'); 			setcookie('theme-class', 'light'); 			mtThemeColor.setAttribute('content', '#29a075'); 		} else { 			$('body').addClass('darkstyle'); 			setcookie('theme-class', 'darkstyle'); 			mtThemeColor.setAttribute('content', '#1a1e29'); 		} 	}, 16); 	 }

const mtThemeColor = document.querySelector('meta[name="theme-color"]'); if(document.cookie.includes("theme-class=darkstyle")){ mtThemeColor.setAttribute('content', '#1a1e29'); } function changeTheme() { setTimeout(function(){ if( $('body').hasClass('darkstyle') ) { $('body').removeClass('darkstyle'); setcookie('theme-class', 'light'); mtThemeColor.setAttribute('content', '#29a075'); } else { $('body').addClass('darkstyle'); setcookie('theme-class', 'darkstyle'); mtThemeColor.setAttribute('content', '#1a1e29'); } }, 16); }

Дополнительно:

собственно, где код ?

  • modelair, добавил в пост
  • Aison, php к мерцаниям отношения не имеет. различия в браузерном коде. найдите их.
    вообще, вы довольно странным способом взялись менять тему.
    meta theme-color не для этого. попробуйте воспроизвести мерцание в песочнице
  • modelair, что? а с чего бы пхп имело отношения к мерцаниям? к мерцаниям имеет отношение размер странцы и js код, который срабатывает не сразу и делает замену цвета в метатеге. если страница маленькая, то никаких мерцаний нет и всё работает быстро. если как у меня, то нунжна секунда, чтобы это прооизошло и в эту секунду виден цвет метатега от светлой темы и вот после этого меняется на цвет тёмной темы... проблема только в этом. когда я писал смену темы чисто на js, то эфект мерцания также писутствовал при обновлении страницы, но включив кеш cms это пропало. сейчас я решил сделать на пхп, чтобы мерцаний не было.

    пхп же наоборот позволяет сделать всё гладко, но мне не хотелось бы ради одног метатега делать это на стороне бэка. да и смена темы через пхп весьма хороша, чего тут странного. довольно просто и эффективно)

  • Aison, так вы же это сами и написали. "если сделать на пхп - мерцаний не будет". мерцает браузер? в браузере только html и js и что такое php он не знает
  • modelair, мерацния это момент смены со светлой на тёмный. допустим, у меня цвет белый. я нажал на кноку и тема сменилась на тёмную. обновил странцу и увидел, что метатег, который окрашивает шторку браузера сначала показывает светлую тему (белым цветом) а потом, когда скрипт сработал после этой перезагрузки она стало тёмной. т.е. скрипт не сразу меняет цвета, есть секунда и это то самое мерцание... надеюсь поняли иначе придётся показывать видео
  • Aison, я понял, но так проблему не задетектишь. надо песочницу.
    а что такое setcookie? точно не нативная js-функция
  • modelair, это функция пхп. setcookie - отправляет cookie
  • Aison, ну, да. что она делает в js-коде, если это функция php?
  • modelair, в смысле? она и в js есть)
  • Aison, нету :)
  • modelair, это пользовательская функция, котрую я могу юзать)
  • Aison, ну вот, ее бы тоже посмотреть, в таком случае
  • modelair, функция принимает имя, и дату, когда печенька помрёт. альтернативный вариант document.cookieи setCookie()
  • modelair, дак а что её смотреть?) код я скинул в посте. это весь код, не считая простенького html.

    проблема только в этом

    const mtThemeColor = document.querySelector('meta[name="theme-color"]'); if(document.cookie.includes("theme-class=darkstyle")){ 	mtThemeColor.setAttribute('content', '#1a1e29'); }

    const mtThemeColor = document.querySelector('meta[name="theme-color"]'); if(document.cookie.includes("theme-class=darkstyle")){ mtThemeColor.setAttribute('content', '#1a1e29'); }

    я Вас не пойму... у меня с пхп нет проблем, там всё работет. мне просто нужно в метатеги менять цвет панельки браузера при смене на тёмную тему. всё это работает, но когда я обновляю страницу, то код не сразу срабатывает от того можно на долю секунды видеть светлый цвет панельки браузера. зайдите сюда с смартфона, смените на тёмную тему и пообновляйте страницу и увидете проблему.

  • Aison, увидел, ага.
  • modelair, а у меня андро и там это есть. каждый раз видно. и у большинства тоже андро) так что это проблема имеет место быть( и я думаю проблема в реализации... придётся делать на пхп значит, чтобы там тоже менялся цвет... других вариантов не вижу пока что, но может кто-то подскажет)
  • Aison, ваши данные генерирует php, верно? тоесть, рисует тег meta именно php, и первое что он делает - рисует его со светлой темой, которая меняется уже на клиенте. рисуйте нужное значение сразу на сервере
  • modelair, нет. этот тег есть в html файле, пхп его не рисует. и там стоит сетлая тема. пхп переключает на тёмну тему. а там жс код есть, который делает проверку на куки и если они стоят от тёмной, то срабатывает условие js и цвет в метатеге заменяется на тёмный. это на стороне клиента уже всё. js медленно это делает. а нужно быстро, сразу. если кеш в cms включить, то проблемы нет, но это не выход. точнее выход, но запасной)
  • Aison, хоспаде, все мы понять друг друга не можем. а html откуда? он готовый и статичный? обычно это дело генерируется на php
  • modelair, статичный
  • А в чем собственно проблема то? На php пусть будет, раз это решает все проблемы, тем более это самый быстрый вариант определить тему.

    Если прям очень хочется на js, то самый быстрый вариант это инлайново прямо в шапке задать условие во время чтения документа, что-то вроде этого:

    &lt;script&gt;             if (cookie === "bla-bla-bla") {                 document.write('&lt;meta name="theme-color" content="#fff" /&gt;');             } else {                 document.write('&lt;meta name="theme-color" content="#000" /&gt;');             }         &lt;/script&gt;

    &lt;script&gt; if (cookie === "bla-bla-bla") { document.write('&lt;meta name="theme-color" content="#fff" /&gt;'); } else { document.write('&lt;meta name="theme-color" content="#000" /&gt;'); } &lt;/script&gt;

  • сделайте чтение из куки до создания этого мета тега и если кука есть, проверьте ее на php далее ее значение подставляйте в тег. Будет вам счастье.
    &lt;? $cookieColor = isset($_COOKIE['theme']) ? $_COOKIE['theme'] : '#000'; // но вам стоит проверять $_COOKIE['theme'] какой-либо регуляркой дабы быть беспечным :) ?&gt; &lt;meta name="theme-color" content="&lt;?=$cookieColor?&gt;" /&gt;

    &lt;? $cookieColor = isset($_COOKIE['theme']) ? $_COOKIE['theme'] : '#000'; // но вам стоит проверять $_COOKIE['theme'] какой-либо регуляркой дабы быть беспечным :) ?&gt; &lt;meta name="theme-color" content="&lt;?=$cookieColor?&gt;" /&gt;

  • Спасибо за ответы) сделал через php
  • сделайте чтение из куки до создания этого мета тега и если кука есть, проверьте ее на php далее ее значение подставляйте в тег. Будет вам счастье. Кривой пример на подумать:

    &lt;? $cookieColor = isset($_COOKIE['theme']) ? intval($_COOKIE['theme']) : 0; // ожидает передачи в куку theme - числа $colorTheme = $cookieColor &lt; 1 ? '#000' : '#fff'; ?&gt; &lt;meta name="theme-color" content="&lt;?=$colorTheme?&gt;" /&gt;

    &lt;? $cookieColor = isset($_COOKIE['theme']) ? intval($_COOKIE['theme']) : 0; // ожидает передачи в куку theme - числа $colorTheme = $cookieColor &lt; 1 ? '#000' : '#fff'; ?&gt; &lt;meta name="theme-color" content="&lt;?=$colorTheme?&gt;" /&gt;

    • всё проще) немного доработал код в этой части (точнее в двух). но всё равно спасибо, отмечу решением за проявленное внимание
      if( $a_hour &gt;= 0 AND ($a_hour &gt; 20 OR $a_hour &lt; 6) ) {         $theme_class = 'darkstyle';         $theme_color = '#000000';      } else {         $theme_class = '';         $theme_color = '#29a075';      }

      if( $a_hour &gt;= 0 AND ($a_hour &gt; 20 OR $a_hour &lt; 6) ) { $theme_class = 'darkstyle'; $theme_color = '#000000'; } else { $theme_class = ''; $theme_color = '#29a075'; }

    • $cookieColor = intval($_COOKIE['theme'] ?? 0);
      Ну или кстати в одну строку
      $colorTheme = empty($_COOKIE['theme']) ? '#000' : '#fff';
    • Aison, святая вера в то, что все пользователи живут в одном часовом поясе )))
    • Ипатьев, можно и тернарные операторы заюзать) но мне и мой вариант норм. да почему, я и до вечера мог подождать и даже до следующего дня) вряд ли что-то особое предложат. сделал вот через пхп и всё прекрасно)
    • Ипатьев, нет, что у них закат и рассвет в одинаковое время
    • Aison,
      $init_c = $a_hour &gt;= 0 &amp;&amp; ($a_hour &gt; 20 || $a_hour &lt; 6) ? 1 : 0; $theme_class = $init_c&gt;0 ? 'darkstyle' : ''; $theme_color = $init_c&gt;0 ? '#000000' : '#29a075';

      $init_c = $a_hour &gt;= 0 &amp;&amp; ($a_hour &gt; 20 || $a_hour &lt; 6) ? 1 : 0; $theme_class = $init_c&gt;0 ? 'darkstyle' : ''; $theme_color = $init_c&gt;0 ? '#000000' : '#29a075';

    • Aison, при чем здесь подождать до следующего дня? Пользователи вашего сайта
    • Ипатьев, да я хз вообще о чём речь...
    • Aison, вы вообще в курсе, что такое часовой пояс? А что пользователи сайта могут жить в разных частях земного шара?
    • Aison, у тебя смена темы зависит от времени сервера.
      И если на твой сайт зайдет человек с другим часовым поясом, то у них это все будет работать не корректно.
      Это я так, просто объяснил, что тебе выше пытаются донести
    • Wispik, это просто возможный вариант использование кода. т.е. это как бы плагин для cms. я использую вторую часть кода, где тема меняется по требованию, а это нажатие на кнопку смены.
    • Ипатьев, я в курсе)
    • Aison, и какую тему увидит пользователь из Хабаровска, когда в датацентре в Москве будет ночь?
    • Ипатьев, какая стоит по умолчанию, а если ему нужна будет тёмная, то нажатием кнопки изменит на тёмную
    • Wispik, и я не оч понимаю, зачем это делать, если вопрос был в другом... это не совсем мой код, но я знаю, что там происходит). я всё равно его уже переписал... ответы я тоже получил. и вопрос решён, но спасибо. можно было просто сразу сказать, а не намёками... я бы тогда сразу сказал, что всё ок и не стоит переживать) я ж мог просто скинуть заготовку кода, который не совсем готов.
    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Ирина WP Ответ

    Для реализации смены на тёмную тему на веб-сайте можно использовать CSS и JavaScript. Вот пример того, как это можно сделать:

    1. Создайте два набора стилей для светлой и тёмной темы:

    /* Стили для светлой темы */
    body {
      background-color: #ffffff;
      color: #000000;
    }
     
    /* Стили для тёмной темы */
    .dark-mode body {
      background-color: #333333;
      color: #ffffff;
    }

    /* Стили для светлой темы */ body { background-color: #ffffff; color: #000000; } /* Стили для тёмной темы */ .dark-mode body { background-color: #333333; color: #ffffff; }

    2. Добавьте кнопку или переключатель, который будет отвечать за смену темы:

    <button>Сменить тему</button>

    <button>Сменить тему</button>

    3. Напишите JavaScript функцию для переключения темы:

    function toggleDarkMode() {
      const body = document.querySelector('body');
      body.classList.toggle('dark-mode');
    }

    function toggleDarkMode() { const body = document.querySelector('body'); body.classList.toggle('dark-mode'); }

    4. Для сохранения выбранной пользователем темы можно использовать Local Storage:

    // Проверяем, есть ли сохранённая тема в Local Storage
    if (localStorage.getItem('theme') === 'dark') {
      document.querySelector('body').classList.add('dark-mode');
    }
     
    // Обновляем тему при смене
    function toggleDarkMode() {
      const body = document.querySelector('body');
      body.classList.toggle('dark-mode');
     
      // Сохраняем выбранную тему в Local Storage
      if (body.classList.contains('dark-mode')) {
        localStorage.setItem('theme', 'dark');
      } else {
        localStorage.setItem('theme', 'light');
      }
    }

    // Проверяем, есть ли сохранённая тема в Local Storage if (localStorage.getItem('theme') === 'dark') { document.querySelector('body').classList.add('dark-mode'); } // Обновляем тему при смене function toggleDarkMode() { const body = document.querySelector('body'); body.classList.toggle('dark-mode'); // Сохраняем выбранную тему в Local Storage if (body.classList.contains('dark-mode')) { localStorage.setItem('theme', 'dark'); } else { localStorage.setItem('theme', 'light'); } }

    Таким образом, пользователь сможет переключать темы на вашем сайте, а их предпочтения будут сохранены даже после обновления страницы.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно