FOUC в светлом режиме

У меня возникли проблемы с появлением нестилизованного (FOUC) контента на моем веб-сайте. у меня есть кнопка для переключения между темным и светлым режимом, причем темный режим используется по умолчанию.

поэтому при обновлении страницы в светлом режиме вы можете увидеть FOUC темного режима до того, как будет применен светлый режим... мне интересно, как этого не допустить.

$(function() {
  var switched = $('#mode');

  switched.on("change", function() {
    if (switched.is(':checked')) {
      $('html').removeClass('dark');
      $('html').addClass('light');
      localStorage.setItem('mode', 'light');

    } else {
      $('html').removeClass('light');
      $('html').addClass('dark');
      localStorage.setItem('mode', 'dark');

    }
  });

  var mode = localStorage.getItem('mode');
  if (mode == 'dark') {
    switched.prop("checked", false);
    $('html').removeClass("light");
    $('html').addClass("dark");
  }
  if (mode == 'light') {
    switched.prop("checked", true);
    $('html').removeClass("dark");
    $('html').addClass("light");
  }

});
:root,
:root.dark {
  --color-bg: #2B2531;
  --color-fg: #FAE5C4;
}

:root.light {
  --color-bg: #DED8F0;
  --color-fg: #2F2131;
}

body {
  background-color: var(--color-bg);
  color: var(--color-fg);
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>

<head>
  <!--CSS then scripts are written here-->
</head>

<body>
  <div class = "boutonmode">
    <div class = "darklightmode">
      <input type = "checkbox" id = "mode">
      <label for = "mode" class = "form-check-label">Mode</label>
    </div>
  </div>
  <h1>test</h1>
</body>

</html>

Что означает «Фук»?

Reporter 06.10.2023 12:24

@Reporter en.wikipedia.org/wiki/Flash_of_unstyled_content

Teemu 06.10.2023 12:26

«Вспышка нестилизованного контента», в моем случае это означает, что темный режим появляется на долю секунды, прежде чем будет применен светлый стиль.

amy 06.10.2023 12:26

«Здесь пишутся CSS и скрипты». Означает ли это, что вы используете встроенные теги style в head вместо того, чтобы связывать таблицы стилей с внешними файлами?

Teemu 06.10.2023 12:31

Нет, у меня есть внешняя таблица стилей!

amy 06.10.2023 12:31

Чтобы избежать этого, вам нужно дождаться запуска JS, прежде чем показывать какой-либо контент, например. своего рода начальное состояние загрузки, которое можно удалить после применения светлых/темных классов.

DBS 06.10.2023 12:36
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
6
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вспышка нестилизованного контента (FOUC) происходит из-за того, что JavaScript требует времени для выполнения и применения стилей. Ваш код сначала загружает страницу в режиме по умолчанию (темном), и только затем он переключается в светлый режим, если в локальном хранилище установлено значение «светлый». Это вызывает кратковременное мигание темы по умолчанию перед применением светлой темы.

Чтобы избежать этого, вам необходимо убедиться, что установлена ​​правильная тема, прежде чем произойдет какой-либо рендеринг. Вот как вы можете это сделать:

  1. Вставьте JavaScript для настройки темы в <head>: Таким образом, стили применяются до визуализации содержимого страницы. Обратите внимание, что это заблокирует рендеринг, что и является целью предотвратить FOUC.

  2. Используйте селектор CSS :not(): по умолчанию стили тела применяются только в том случае, если элемент <html> не имеет класса dark или light. Это предотвратит применение стилей по умолчанию до запуска JavaScript.

Вот модифицированная версия вашего кода:

HTML:

<!DOCTYPE html>
<html>
<head>
    <!-- Inline your CSS here for immediate styling -->
    <style>
        :root,
        :root.dark {
            --color-bg: #2B2531;
            --color-fg: #FAE5C4;
        }

        :root.light {
            --color-bg: #DED8F0;
            --color-fg: #2F2131;
        }

        body:not(.light):not(.dark) {
            display: none; /* Prevent FOUC by hiding content until mode is determined */
        }

        body {
            background-color: var(--color-bg);
            color: var(--color-fg);
        }
    </style>

    <script>
        // Set theme before page renders
        var mode = localStorage.getItem('mode');
        if (mode == 'light') {
            document.documentElement.classList.add('light');
        } else {
            document.documentElement.classList.add('dark'); // This is your default theme
        }
    </script>
    <script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
    <div class = "boutonmode">
        <div class = "darklightmode">
            <input type = "checkbox" id = "mode">
            <label for = "mode" class = "form-check-label">Mode</label>
        </div>
    </div>
    <h1>test</h1>
    <script>
        // Theme switcher code
        $(function() {
            var switched = $('#mode');

            switched.on("change", function() {
                if (switched.is(':checked')) {
                    $('html').removeClass('dark');
                    $('html').addClass('light');
                    localStorage.setItem('mode', 'light');
                } else {
                    $('html').removeClass('light');
                    $('html').addClass('dark');
                    localStorage.setItem('mode', 'dark');
                }
            });

            if (mode == 'light') {
                switched.prop("checked", true);
            } else {
                switched.prop("checked", false);
            }
        });
    </script>
</body>
</html>

Вот что мы сделали:

  • Логика настройки темы перенесена в заголовок документа.
  • Установите отображение body по умолчанию на none до тех пор, пока к light не будет применен класс dark или <html>. Это всего лишь дополнительный шаг к тому, чтобы не было FOUC.

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

Другие вопросы по теме