Существует множество предложений по управлению значениями цвета с помощью Sass. Вы можете создавать палитры программно , полагаться на цветовые функции Sass , правильно называть переменные или даже позволить математике выбрать все свои цвета за вас .
Однако что, если все, что вы хотите сделать, это выбрать группу базовых цветов и использовать одинаковые темные / светлые / прозрачные варианты для каждого из этих цветов? Мы можем сделать это довольно легко с парой карт Sass и одной функцией.
Карта цветов
Во-первых, мы собираемся начать с хранения всех наших основных цветов на карте (AKA, массив Sass).
$colors: ( red: #ff4136, blue: #0074d9, yellow: #ffdc00, orange: #ff851b );
Начиная с Sass 3.3, SassScript предоставляет нам несколько функций для доступа к данным на карте . В дальнейшем мы будем использовать функции map-has-keys()
и map-get()
.
Карта вариаций
Теперь мы создадим карту для хранения изменений, которые мы должны сделать для каждого из основных цветов. Карта $variations
будет содержать эту информацию. Мы собираемся использовать возможность хранения карт внутри карт, чтобы организовать это хорошо. Давайте посмотрим, как мы организуем эту информацию.
Во-первых, каждое название вариации цвета — это сокращение, которое мы будем использовать, чтобы описать это изменение цвета и позже вызвать его из нашей функции. Это имя является ключом для карты с двумя значениями: именем цветовой функции Sass Script и параметрами, которые нужны функции. Значение function
должно соответствовать функции из списков функций RGB, функций HSL или непрозрачности .
Значением parameters
должны быть любые параметры, которые нужны функции в дополнение к исходному цвету. Если вы посмотрите на пример карты $variations
, вы увидите, что для lighten
нужны два параметра: исходный цвет (который мы получим из $colors
) и сумма для изменения, которое мы будем хранить здесь в parameters
. С другой стороны, для grayscale
нужен только начальный цвет, поэтому нам вообще не нужно включать parameters
для этой вложенной карты. Функция mix
вызываемая «shade», принимает до трех аргументов: начальный цвет, микс-цвет и процентное содержание того, какая часть «mix» должна быть первым цветом. Мы просто включили оба дополнительных параметра в разделенный пробелами список.
$variations: ( light: ( function: lighten, parameters: 15% ), dark: ( function: darken, parameters: 10% ), fade: ( function: rgba, parameters: .7 ), gray: ( function: grayscale ), shade: ( function: mix, parameters: white 80% ) );
Функция для генерации цветов
Теперь самое интересное: единственная функция, которая получает цвет, вносит изменения, а затем возвращает правильное значение для использования. Во-первых, давайте посмотрим на всю функцию. Затем мы пройдем его по одному шагу за раз.
@function color-variation($color, $variation: false) { @if map-has-key($colors, $color) { $color: map-get($colors, $color); } @else { @if type-of($color) != color { @error "Invalid color name: `#{$color}`."; } } @if $variation { @if not map-has-key($variations, $variation) { @error "Invalid $variation: `#{$variation}`."; } @else { $this-variation: map-get($variations, $variation); $args: join(map-get($this-variation, function), $color); @if map-get($this-variation, parameters) { $args: join($args, map-get($this-variation, parameters)); } @return call($args...); } } @return $color; }
Сначала вы должны заметить, что функция принимает два аргумента. Требуется название цвета (который, вероятно, будет ключом от $colors
) ( да, я сказал «вероятно» — скоро об этом ), а название варианта (которое должно совпадать с ключом из $variations
) необязательно ,
Проверка значения цвета
@if map-has-key($colors, $color) { $color: map-get($colors, $color); } @else { @if type-of($color) != color { @error "Invalid color name: `#{$color}`."; } }
Первый оператор @if
гарантирует, что у нас есть правильное значение цвета для работы. Если строка, переданная как цвет в $colors
, будет использовано соответствующее значение из карты. Но что, если вы передадите что-то не в $colors
? @else
половина этой операции обрабатывает эту ситуацию.
Для начала он проверяет, является ли аргумент $color
действительным цветом CSS или нет. Если $color
не является допустимым цветом (мы уже знаем, что он не в $colors
), мы сгенерируем компилятор @error
и сообщим, что вам нужно использовать правильный цвет. С другой стороны, если ваш $color
сам по себе является допустимым значением цвета (имя цвета HTML, RGB (A) или HSL), мы просто продолжим и будем использовать это значение. Это дает нашей функции color-variation()
более широкий охват. Например, вы можете использовать его для одноразового значения цвета (конечно, экономно — если вы повторяете значение цвета, оно, вероятно, должно быть на карте).
Примечание: если вы хотите заставить себя или других разработчиков придерживаться значений в карте $colors
, просто удалите две строки: @if type-of($color) != color {
и его закрытие }
две строки ниже. Оставьте оператор @error
внутри блока @else
в @else
он находится.
Теперь, когда у нас есть правильный цвет, давайте применим правильный вариант к нему.
Проверка имени варианта
@if $variation { @if not map-has-key($variations, $variation) { @error "Invalid $variation: `#{$variation}`."; } @else { //... } }
Первый оператор @if
проверяет, @if
ли мы вообще имя варианта. В конце концов, эта функция должна будет возвращать неизменное значение цвета, верно? Правильно. В вашем Sass вы будете использовать color: color-variation(orange);
чтобы получить один из определенных цветов в значении свойства CSS.
Далее, мы используем функцию map-has-key()
чтобы убедиться, что имя варианта, которое мы передаем, на самом деле находится в карте $variations
. Если нет, мы явно @error
в компилятор. Это обеспечит немедленную обратную связь о том, что мы допустили ошибку, и заставит нас исправить ее, прежде чем мы продолжим.
Примечание. Если вы хотите разрешить совершать ошибки сейчас и исправлять их позже, замените @error
на @warn
. @warn
отправит вашему компилятору «более мягкое» сообщение об ошибке, и эта функция просто вернет значение цвета без изменений.
Изменение цвета
$this-variation: map-get($variations, $variation); $args: join(map-get($this-variation, function), $color); @if map-get($this-variation, parameters) { $args: join($args, map-get($this-variation, parameters)); }
Здесь мы получаем данные, присвоенные нашему текущему варианту, и назначаем их новой переменной. Помните, что $variations
карте $variations
содержится несколько других карт, поэтому этот шаг облегчает работу с вложенными парами ключ / значение для текущего варианта.
Мы собираемся добавить $args
сейчас. В конечном итоге нам потребуется передать список значений (имя функции, цвет, аргументы вариации) в функцию call()
и $args
сохранит этот список. Мы начнем с использования join()
чтобы объединить имя функции текущего варианта ( map-get($this-variation, function)
) со значением $color
мы проверяли выше (мы могли бы использовать append()
вместо объединения здесь ).
Затем наша функция проверяет, есть ли пара ключ / значение параметров для $this-variation
. Если нет, он переходит к оператору call()
. Но если есть параметры, мы добавляем в список $args
, присоединяя к нему значение / список в текущих parameters
. Теперь у нас есть список, который нам нужен: имя функции, начальный цвет и дополнительные аргументы для функции.
@return call($args...);
Эта последняя строка возвращает результаты передачи нашего списка $args
в функцию call()
. call()
динамически генерирует и запускает функцию. Первым параметром, который он принимает, является имя функции, и любые дополнительные параметры передаются этой функции в качестве аргументов.
Вывод
Чтобы использовать эту функцию в своих собственных проектах, создайте свою собственную карту имен и значений цветов, карту функций и параметров color-variation()
и используйте функцию color-variation()
чтобы получить значение цвета, которое вам нужно в частичках Sass.
Бонус: если вам не нравится вводить «color-variation ()» снова и снова, используйте псевдоним cv()
в качестве сокращенной функции:
@function cv($color, $variation:false) { @return color-variation($color, $variation); }
Если вы хотите увидеть весь код для этого, то посмотрите источник в этой книге .