CSS Quickies: CSS-переменные — или как легко создать «светлую / темную» тему

CSS Quickies: CSS-переменные - или как легко создать «светлую / темную» тему

От автора: что такое CSS Quickes? Я спросил в своем любимом сообществе в Instagram: «Какие свойства CSS сбивают вас с толку?» В «CSS Quickies» я подробно объясняю одно свойство CSS. Это свойства, которые просят пояснить члены.

Давайте поговорим о Пользовательских свойствах, также известных как Переменные CSS. В заключение! Работали вы когда-нибудь с CSS и хотели сохранить свой дизайн согласованным? Или было больше похоже на то, что на некоторых страницах ваш сайт имел различный отступ, поля или цвета?

Может быть, вы хотели реализовать темную тему? Это было возможно и раньше, но теперь это стало проще! Конечно, если вы использовали LESS или SASS, тогда вы имели там переменные, и теперь они наконец-то поддерживаются нативно. Давайте начнем!

Определение переменной CSS

Вы определяете переменную CSS с префиксом свойства CSS с помощью —. Давайте посмотрим на некоторые примеры.

:root{ --example-color: #ccc; --example-align: left; --example-shadow: 10px 10px 5px 0px rgba(0,0,0,0.75);
}

Ваш первый вопрос: «Что это за псевдо-класс?». Хороший вопрос! Псевдо-класс :root это то, как вы бы использовали селектор html, за исключением того, что специфичность псевдо-класса :root выше. Это означает, что если вы установите свойства для псевдо-класса :root, они переопределят селектор html.

Ладно, все остальное довольно просто. Пользовательское свойство —example-color имеет значение #ccc. Когда мы используем пользовательское свойство, например, для свойства background-color, фон этого элемента будет светло-серым. Круто верно?

Вы можете назначить пользовательское свойство, то есть переменную CSS, каждому значению, которое вы можете задать для любого другого свойства в CSS. Вы можете использовать left, например, 10px и так далее.

Использование переменных CSS

Теперь, когда мы знаем, как устанавливать переменные CSS, нам нужно научиться их использовать! Для этого нам нужно изучить функцию var(). Она принимает два аргумента. Первый аргумент должен быть пользовательским свойством. Если пользовательское свойство недопустимо, вам нужно задать резервное значение. Для этого вам просто нужно установить второй аргумент функции var(). Давайте рассмотрим пример.

:root{ --example-color: #ccc;
} .someElement { background-color: var(--example-color, #d1d1d1);
}

Это должно быть довольно просто. Мы устанавливаем для —example-color — #ccc, а затем используем его для .someElement, чтобы задать цвет фона. Если что-то пойдет не так, и —example-color будет недействительно, у нас будет резервное значение #d1d1d1.

Что произойдет, если вы не установите запасное резервное и ваша пользовательская переменная будет недействительной? Браузер будет действовать так, как будто это свойство не указано, и выполнит свою обычную работу.

Советы и приемы

Несколько резервных значений

Что если вы хотите иметь несколько резервных значений? Вы можете подумать, что возможно следующее:

.someElement { background-color: var(--first-color, --second-color, white);
}

Это не будет работать. После первой запятой var() обрабатывает все, даже запятые, как значение. Браузер изменит это в background-color: —second-color, white;. Это не то, что нам нужно. Чтобы иметь несколько значений, мы можем просто вызвать var() внутри var(). Вот пример:

.someElement { background-color: var(--first-color, var(--second-color, white));
}

Теперь это даст желаемый результат. Когда и —first-color, и —second-color недействительны, браузер установит цвет фон white.

Что если моему запасному значению нужна запятая?

Что делать, если, например, вы хотите установить значение font-family и в качестве запасного значения вам нужно указать более одного шрифта? Учитывая пример выше, это должно быть понятно. Мы просто пишем все с запятыми. Например:

.someElement { font-family: var(--main-font, "lucida grande" , tahoma, Arial);
}

Здесь мы видим, что после первой запятой функция var() обрабатывает все как одно значение.

Установка и получение пользовательских свойств в Javascript

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

const element = document.querySelector('.someElement');
// Get the custom propety
element.style.getPropertyValue("--first-color");
// Set a custom propety
element.style.setProperty("--my-color", "#ccc");

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

Создание переключателя тем с помощью пользовательских свойств

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

HTML-разметка

<div class="grid theme-container"> <div class="content"> <div class="demo"> <label class="switch"> <input type="checkbox" class="theme-switcher"> <span class="slider round"></span> </label> </div> </div>
</div>

На самом деле ничего особенного здесь нет. Мы будем использовать CSS grid для центрирования контента, поэтому у нас в первом элементе есть класс .grid, классы .content .demo предназначены только для стиля. Два важных класса здесь .theme-container и .theme.switcher.

Код Javascript

const checkbox = document.querySelector(".theme-switcher"); checkbox.addEventListener("change", function() { const themeContainer = document.querySelector(".theme-container"); if (themeContainer && this.checked) { themeContainer.classList.add("light"); } else { themeContainer.classList.remove("light"); }
});

Сначала мы выбираем элемент ввода .theme-switcher и элемент .theme-container. Затем мы добавляем прослушиватель событий, который прослушивает изменения. Это означает, что каждый раз, когда вы нажимаете на элемент ввода, будет выполняться обратный вызов для этого прослушивателя событий.

В операторе if мы проверяем, существует ли .themeContainer и выбран ли чек-бокс. Когда это так, мы добавляем в .themeContainer класс .light, в противном случае мы удаляем его. Почему мы удаляем и добавляем класс .light? Ответ через секунду.

Код CSS

Поскольку этот код длинный, я поясню вам его шаг за шагом!

.grid { display: grid; justify-items: center; align-content: center; height: 100vh; width: 100vw;
}

Давайте сначала отцентрируем наш контент. Мы делаем это с помощью CSS grid. Мы расскажем о функции grid в следующем разделе, посвященном CSS!

:root { /* light */ --c-light-background: linear-gradient(-225deg, #E3FDF5 0%, #FFE6FA 100%); --c-light-checkbox: #fce100; /* dark */ --c-dark-background:linear-gradient(to bottom, rgba(255,255,255,0.15) 0%, rgba(0,0,0,0.15) 100%), radial-gradient(at top center, rgba(255,255,255,0.40) 0%, rgba(0,0,0,0.40) 120%) #989898; --c-dark-checkbox: #757575;
}

Это много кода и цифр, но на самом деле мы здесь мало что делаем. Мы готовим пользовательские свойства для использования в теме. —c-dark- и —c-light — это то, что я выбрал в качестве префикса пользовательских свойств. Мы определили светлую и темную тему. Для нашего примера нам просто нужен цвет checkbox и свойство background, которое задано у нас градиентом.

.theme-container { --c-background: var(--c-dark-background); --c-checkbox: var(--c-dark-checkbox); background: var(--c-background); background-blend-mode: multiply,multiply; transition: 0.4s;
}
.theme-container.light { --c-background: var(--c-light-background); --c-checkbox: var(--c-light-checkbox); background: var(--c-background);
}

Теперь мы понимаем, почему использовали имя .theme-container. Теперь у нас есть глобальные пользовательские переменные. Мы не хотим использовать специфичные пользовательские переменные. Нам нужны глобальные пользовательские переменные. Вот почему мы устанавливаем —c-background. Теперь мы будем использовать только глобальные пользовательские переменные. После этого мы устанавливаем background.

.demo { font-size: 32px;
} /* The switch - the box around the slider */
.switch { position: relative; display: inline-block; width: 60px; height: 34px;
} /* Hide default HTML checkbox */
.switch .theme-switcher { opacity: 0; width: 0; height: 0;
}

Это всего лишь стандартный код для установки стиля. В селекторе .demo мы устанавливаем font-size. Это размер символов для переключателя. В селекторе .switch height и width — это то, насколько высоким и широким будет элемент нашего символа переключения.

/* The slider */
.slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: var(--c-checkbox); transition: 0.4s;
} .slider:before { position: absolute; content: "night"; height: 0px; width: 0px; left: -10px; top: 16px; line-height: 0px; transition: 0.4s;
} .theme-switcher:checked + .slider:before { left: 4px; content: "sun"; transform: translateX(26px);
}

Здесь мы наконец можем увидеть пользовательские свойства в действии, кроме использования их непосредственно в .theme .container, а также снова много стандартного кода. Как видите, символы переключения — это простые символы Unicode. Вот почему переключатель будет выглядеть по-разному на разной ОС. Вы должны иметь это в виду. Важно знать, что в селекторе .slider:before, мы смещаем наш символ с помощью свойств left и top. Мы делаем это также в .theme-switcher:checked + .slider:before, но только с помощью свойства left.

/* Rounded sliders */
.slider.round { border-radius: 34px;
}

Это опять-таки только стилизация. Чтобы наш переключатель был закругленным. Вот и все! Теперь у нас есть переключатель тем, который можно расширять.

Источник: https://dev.to

Редакция: Команда webformyself.