Статьи

Управление значениями цвета с помощью Sass

Существует множество предложений по управлению значениями цвета с помощью 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); } 

Если вы хотите увидеть весь код для этого, то посмотрите источник в этой книге .