Статьи

Динамическая градиентная текстовая функция в Sass

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

Немного предыстории …

Возможность изменять цвет текста в зависимости от фона является распространенным требованием, один из способов сделать это — проверить яркость фона, а затем соответствующим образом изменить текст. Для этого существует популярная и хорошо документированная функция …

@function set-notification-text-color($color) {
  @if (lightness($color) > 50) {
    @return #000000; // Lighter background, return dark color
  } 
  @else {
    @return #ffffff; // Darker background, return light color
  }
}

Вышеуказанная функция применяется так:

 .notification-confirm {
  background: $notification-confirm;
  color: set-notification-text-color($notification-confirm);
}

Шаг 1 — Фоновый градиентный миксин

Прежде чем мы рассмотрим функцию градиента текста, нам нужно создать список для хранения значений нашего фонового градиента и создать миксин…

 $list: $orange, $white, $orange, $white;

Этот список выше и направление используются в качестве аргументов для фонового миксина. Использование списка имеет два основных преимущества: во-первых, он имеет неограниченное количество аргументов, допускающих любую комбинацию цветов и / или процентов. Во-вторых, и, что важно, для этой функции мы можем перебирать список, чтобы создать такое же количество новых значений для градиента текста. Более подробную информацию о аргументах mixin и о том, когда их использовать, можно найти в этом посте .

Градиентный миксин выглядит так:

 @mixin gradient($direction, $list) {
  background: -webkit-linear-gradient($direction, $list);
}

и применяется так:

 .text {
  @include gradient(left, $list);
}

Шаг 2 — Функция градиента текста

В браузерах на основе webkit / blink можно отображать градиенты текста, используя свойство text clip вместе с text-fill-color, как показано ниже:

 .text {
  background: -webkit-linear-gradient(left, #000, #fff); // We will need to generate gradient colors to complement the background.
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

Во-первых, нам нужно создать функцию с тем же значением $ list, что и аргумент. Функция создаст новый пустой список для хранения наших новых значений, а затем вернет их:

 @function text-color($list){
  $text-list:();
  @return $text-list;
}

Затем мы пробегаем каждое значение в $ list:

 @function text-color($list){
  $text-list:();
  @each $color in $list {
    // Do something...
  }
  @return $text-list;
}

Внутри нашего для каждого цикла мы можем запустить ту же проверку, что и функция сплошного цвета, упомянутая в начале этого поста:

 @function text-color($list){
  $text-list:();
  @each $color in $list {
    @if lightness($color) > 50% {
      // Create a dark text color
    } 
    @else {
      // Create a light text color
    }
  }
  @return $text-list;
}

Чтобы создать темный или светлый цвет текста, нам нужно добавить значение в $ text-list. Это делается с помощью функции добавления:

 $text-list:append($text-list, $black, comma);  // Adds $black to $text-list
$text-list:append($text-list, $white, comma); // Adds $white to $text-list

Таким образом, конечная функция будет:

 @function text-color($list){
  $text-list:();
  @each $color in $list {
    @if lightness($color) > 50% {
      $text-list:append($text-list, $black, comma);
    } 
    @else {
      $text-list:append($text-list, $white, comma);
    }
  }
  @return $text-list;
}

Функция применяется к аргументу градиента $ list в текстовом элементе:

 .text-block {
  @include gradient(left, $list);
  p {
    @include gradient(left, text-color($list));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
  }
}

Sass цветовые функции:

Эта функция хороша в большинстве случаев, но она немного ограничительна тем, что текст может быть только черным или белым. Используя некоторые из встроенных в Sass манипуляций с цветом, функция может генерировать цвет текста динамически на основе ввода, устраняя необходимость в операторе if. Вот несколько примеров:

 @function text-color($list){
  $text-list:();
  @each $color in $list {
    $text-list:append($text-list, invert($color), comma);
  }
  @return $text-list;
}

@function text-color($list){
  $text-list:();
  @each $color in $list {
    $text-list:append($text-list, complement($color), comma);
  }
  @return $text-list;
}

@function text-color($list){
  $text-list:();
  @each $color in $list {
    $text-list:append($text-list, adjust-hue($color, 40deg), comma);
  }
  @return $text-list;
}

Взять вещи немного дальше:

Как я упоминал ранее, ключевой причиной использования списка в качестве параметра градиента является возможность использовать его в качестве многомерного списка. Пример ниже добавляет проценты, чтобы дать немного больше контроля над градиентом …

 $list: ($orange 0%),
       ($orange 50%),
       ($white 50%),
       ($white 100%);

Это процентное значение также необходимо добавить в функцию:

 @function text-color($list){
  $text-list:();
  @each $color, $percentage in $list {
    $text-list:append($text-list, invert($color), $percentage, comma);
  }
  @return $text-list;
}

Используя ключевые кадры CSS, мы можем анимировать градиент для создания интересных эффектов для индикаторов выполнения или загрузки анимации. Демонстрации некоторых из обсуждаемых эффектов можно найти в этом CodePen .

Ограничения и недостатки

Как я уже упоминал ранее, текстовые градиенты работают только в браузерах blink / webkit, однако мы можем гарантировать, что они ухудшаются в других браузерах. Для этого просто используйте префикс webkit только для ваших свойств градиента, заливки и фона для этого метода. Вы также можете добавить запасной цвет и фон в миксин…

 @mixin gradient($direction, $list) {
  background: $white; // Fallback solid background color for unsupported browsers
  background: -webkit-linear-gradient($direction, $list);
}

p {
  color: $orange; // Fallback solid text color for unsupported browsers
  @include gradient(left, text-color($list));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}