CSS переменные и цветовая тема для сайта в несколько строк

  • Tutorial

Один из способов использовать CSS переменные уже сегодня


Создадим сайт который динамически поддерживает светлую, тёмную и цветовые темы.


Интерактивное демо



Создаём базовый цвет который будет меняться. Привязываем его к data-theme на html.


в примерах кода используется & из less/scss синтаксиса


html[data-theme='green'] {
    --theme-color: 110;
}

Теперь нам нужны сами цвета. А точнее их яркость и насыщенность. Для этого будем использовать схему hsl. Помещаем все переменные в :root.


:root {
    --color: ~'hsl(var(--theme-color), 15%, 44%)';
    --background-color: ~'hsl(var(--theme-color), 30%, 10%)';
}

Ну вот. Дело за малым. Хватаем нужный элемент и применяем к нему нашу переменную.


.class-name {
    color: var(--color);
    background-color: var(--background-color);
}

Теперь будем менять контрастность. Заменяем :root на html[с атрибутом].


// :root = html
html {
    &[data-theme-style='normal'] { }
    &[data-theme-style='dark'] { }
}

Теперь для каждой темы берём свои s,l значения.


html {
    &[data-theme-style='normal'] {
        --color: ~'hsl(var(--theme-color), 15%, 44%)';
        --background-color: ~'hsl(var(--theme-color), 30%, 10%)';
    }
    &[data-theme-style='dark'] {
        --color: ~'hsl(var(--theme-color), 70%, 31%)';
        --background-color: ~'hsl(var(--theme-color), 3%, 3%)';
    }
}



Links:
Интерактивное демо
За идею спасибо Marcin Wichary

Реклама
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее

Комментарии 11

    0
    Привет) Классная идея! Простенько и со вкусом…
    Недавно у меня тоже была задача, добавить в имеющееся приложение темы…
    Но там параметры saturation и lightness из hsl у каждой темы отличались…
    Пришлось делать на hex + небольшие добавки из rgba, где нужна была прозрачность.
    Что то типа такого (вместе с scss):

    :root {
        --color: #CCC;
        --background: #FFF;
        --background-rgb: 0, 0, 0;
    }
    
    $color: var(--color);
    $background: var(--background);
    $background-rgb: var(--background-rgb);
    
    .background-with-opacity {
        color: $color;
        background: rgba($background-rgb, $opacity);
    }
    


    По всему проекту были использованы scss переменные, поэтому просто загнал css переменные в scss, можно было создать мапу для них и тд.

    Что-нибудь можешь подсказать для такого случая? Просто думаю можно улучшить, но что именно — в голову пока не лезет. Можно по-идее сделать так:

    :root {
        --background: 0, 0, 0;
    }
    $background: rgb(var(--background));
    $background-rgb: rgba(var(--background-rgb), $opacity);
    


    Но с hex удобнее работать, почти все что нужно менять — цвета без прозрачности. С прозрачностью остаются почти всегда такими же, какие они и были.
      +2

      В примерах кода в статье используется не CSS, а некий препроцессор CSS. Ни в статье, ни в тегах нет указания названия этого препроцессора. Это сбивает с толку, особенно начинающих, потому что не ясно, где заканчивается синтаксис CSS и начинается синтаксис препроцессора. Хотя ничего не мешает написать примеры на простом CSS.


      Примеры кода из статьи на чистом CSS

      (те из них, которые не являются CSS-кодом)


      :root {
          --color: hsl(var(--theme-color), 15%, 44%);
          --background-color: hsl(var(--theme-color), 30%, 10%);
      }

      /* :root = html */
      html[data-theme-style='normal'] { }
      html[data-theme-style='dark'] { }

      html[data-theme-style='normal'] {
          --color: hsl(var(--theme-color), 15%, 44%);
          --background-color: hsl(var(--theme-color), 30%, 10%);
      }
      html[data-theme-style='dark'] {
          --color: hsl(var(--theme-color), 70%, 31%);
          --background-color: hsl(var(--theme-color), 3%, 3%);
      }
        0
        В вашем примере полностью корректный css код, без использования препроцессоров.
          +1

          Верно. Я перевёл примеры кода в статье с синтаксиса препроцессора на чистый CSS.

            +1
            Прошу прощения, некорректно понял ваш комментарий.
        0

        Зачем здесь вообще использовать препроцессор? Просто пишем:


        [data-theme-style='normal'] {
          --color: hsl(var(--theme-color), 15%, 44%);
          --background-color: hsl(var(--theme-color), 30%, 10%);
        }

        Так избавляемся от лишней вложенности, повышения специфичности, трудного чтения препроцессорного костыльного (~'...') кода. А отвязка от html в селекторе дает возможность оформить разные элементы на странице разными темами, например, секции на лендинге.


        <section data-theme-style="normal"><!-- content --></section>
        <section data-theme-style="dark"><!-- content --></section>
          0

          Спасибо, товарищ ментор ;)

            0
            Да, а про browser support никто даже и не думает.
              0
              Все современные браузеры его поддерживают, а кто не поддерживает есть синтаксис с дефолтным цветом)
              А вообще про ie11 давно пора забыть. Или ты на гриды тоже хэйтишь из-за поддержки?)
                0
                Забыть то и я хочу забыть но проект-менеджеры просят поддержку чуть ли не всех браузеров.
                  0
                  ну это уже другая тема для разговора. Хотя пушить их нужно

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

            Самое читаемое