Dark-режим в Berry CSS

Berry CSS позволяет работать в dark-режиме (темном режиме браузера).

Что такое dark-режим?

Некоторым пользователям нравится смотреть сайты в темном режиме. Это когда используется темный фон со светлыми буквами.

Этот блок меняет стили в зависимости от dark-режима.

Для того, чтобы включить dark-режим, нужно указать у родительского элемента класс .dark. Если dark-режим нужен для всего сайта, то его следует указывать у тэга html: <html class="dark">

Переключение dark-режима пользователем

Скорее всего dark-режим будет включаться пользователем сайта вручную. Для этого на сайте можно разместить js-код, который будет прописывать и снимать класс .dark у тега html.

Для того, чтобы автоматически принимать этот класс для всех страниц сайта, следует в секции head считать данные из LocalStorage:

<script>
    const SITE_HOST = window.location.hostname; 
    const KEY_THEME_DARK = `theme.${SITE_HOST.replace(/\//g, '_')}`;
    const KEY_THEME_SELECTED = `theme-selected.${SITE_HOST.replace(/\//g, '_')}`;

    if (localStorage.getItem(KEY_THEME_DARK) === null) {
        theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
        localStorage.setItem(KEY_THEME_DARK, theme);
    }

    if (localStorage.getItem(KEY_THEME_DARK) === "dark") {
        document.documentElement.classList.add("dark");
    }

    function toggleThemeDark() {
        const isDark = document.documentElement.classList.toggle("dark");
        localStorage.setItem(KEY_THEME_DARK, isDark ? "dark" : "light"); 
        return isDark;
    }
</script>

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

Если использовать Alpine.JS, то переключение можно реализовать следующим кодом:

<span 
    x-data="{isDark: localStorage.getItem(KEY_THEME_DARK) === 'dark'}" 
    @click="isDark = toggleThemeDark();" 
    :class="isDark ? 'bi-moon' : 'bi-sun-fill'" 
    class="b-inline cursor-pointer" title="Dark/Light"></span>

В этом примере формируются иконки Bootstrap Icons, которые переключают класс .dark у тега html с помощью функции toggleThemeDark().

Использование dark-режима по умолчанию

Для этого достаточно принудительно прописать класс .dark у тега html.

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

Семантика dark-режима

С помощью классов с префиксом dark: можно явно указывать желаемые цвета в dark-режиме.

<p class="t-primary500 bg-gray100 dark:t-primary200 dark:bg-gray700">Текст</p>
<!-- 
    цвет текста: primary500
    цвет фона: gray100
    
    цвет текста в dark-режиме: primary200
    цвет фона в dark-режиме: gray700
 -->

Dark-режим поддерживается для всех классов всех цветов, а также hover-, bor-, gr- и других. Таким образом можно использовать dark-классы для любого блока.

Переопределение css-переменных для dark-режима

Поскольку Berry CSS управляется через css-переменные, то во многих случаях будет проще просто переопределить некоторые из них для dark-режима.

Рекомендуется такой вариант (который вы можете переопределить под свои задачи):

.dark {
    --body-bg: var(--primary950);
    --body-color: var(--primary300);
    
    --link-color: var(--primary500);
    --link-hover-color: var(--primary600);
    
    --form-input-background: var(--primary900);
    --form-input-color: var(--primary200);
    --form-input-border: 1px solid var(--primary750);

    --form-input-focus-border-color: var(--primary600);
    --form-input-focus-shadow: 0 0 0 0.1rem var(--primary700);
    --form-input-focus-background: var(--primary750);
    --form-input-focus-color: var(--primary150);
    --placeholder-color: var(--primary500);
    
    --button-bg-color: var(--primary700);
    --button-text-color: var(--primary100);
    
    --button-disabled-bg-color: var(--gray600);
    --button-disabled-text-color: var(--gray200);
    
    --pre-bg-color: var(--primary800);
    --pre-text-color: var(--primary200);
    
    --pre-border-top: var(--primary700) solid 1px;
    --pre-border-right: var(--primary700) double 3px;
    --pre-border-bottom: var(--primary700) solid 1px;
    --pre-border-left: var(--primary700) double 3px;
    
    --code-background-color: var(--primary550);
    --code-text-color: var(--primary100);
    
    --mark-background-color: var(--primary500);
    --mark-text-color: var(--primary100);
    
    --var-background-color: hsl(var(--accent-hue) var(--accent-sat) 40%);
    --var-text-color: hsl(var(--accent-hue) var(--accent-sat) 90%);
    
    --kbd-background-color:  var(--primary650);
    --kbd-text-color:  var(--primary100);
    --kbd-border: 1px var(--primary600) solid;
    
    --samp-background-color: var(--primary700);
    --samp-text-color: var(--primary200);
    
    --table-th-background   : var(--primary700);
    --table-tr-border-bottom: var(--primary600) 1px solid;
    --table-th-border-top   : var(--primary600) 1px solid;
    --table-th-border-bottom: var(--primary600) 1px solid;
    --table-th-border-right : var(--primary600) 1px solid;
    --table-tr-hover-bg: var(--primary750);
    
    --table-td-border-right: var(--primary600) 1px solid;
    
    --table-striped-odd-bg : var(--primary650);
    --table-striped-even-bg: var(--primary600);
    
    --hr-border: 1px solid var(--primary300);
    
    --bordered: var(--primary600) 1px solid;
    
    --thumbnail-border: var(--primary700) 1px solid;
}

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