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, '_')}`;

    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().

Использование функции light-dark()

CSS-функция light-dark() позволяет переключать два значения в зависимости от светлой или темной темы пльзователя. Для этого используется css-свойство color-scheme (light/dark). В Berry CSS по умолчанию используется сетлый режим:

:root {
    color-scheme: light; 
}

А для класса .dark он меняется на темный:

.dark {
    color-scheme: dark;
}

Таким образом можно использовать light-dark() для любых произвольных стилей:

<div style="background-color: light-dark(var(--red200), var(--green800))">Text</div>

В этом примере цвет блока в светлом режиме будет red200, а в темном изменится на green800.

Использование 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-режим, то браузер автоматически применит эти переменные для отображения всего сайта.