В этом, без сомнения, прекрасном препроцессоре есть большое количество функций, в том числе и для работы с цветом. Цвет можно насыщать, делать прозрачнее, вытаскивать определенные цвета, конвертировать из hex'а в rgb, а потом в hsl и обратно, смешивать и многое другое. Конечно же, есть функция и для осветления цвета - lighten . Замечательная функция, которая даже работает по правилам.

6.25% - процент одного тона

Опытным путем я выяснил, что 6.25% - это процент, который нужно использовать в функции lighten, чтобы осветлить цвет на один тон и позже станет понятно почему.

// SASS
body
  color: lighten(#889fa8, 6.25%) // => #9aaeb5

// SCSS
body {
  color: lighten(#889fa8, 6.25%); // => #9aaeb5
}

У меня появилась потребность работать с цветом осветляя и затемняя его, именно на один или несколько тонов. Это значит, что осветляя цвет #555555, я жду цвет #656565. Очень важно, чтобы метод работал не только с серой палитрой, но и цветной. Чтобы при осветлении цвета #889fa8 был получен #98afb8, вместо #9aaeb5, выдаваемого функцией lighten. Работать с тоном практичней, когда подбираешь цвет для ссылки с псевдоклассом :hover или для эффекта вдавленного текста, когда нужно сделать границы блока на тон темнее да и вообще везде, где попало)

Вы наверное уже заметили, что каждое второе значение в hex'е цвета - полутон, остается неизменным. Для меня это важно и ребята из Mozilla согласны.

Если открыть панель разработчика, выделить любой hex, найденный в стилях и нажать Shift+↑, то вы увидите именно то поведение, которое я попытался воспроизвести.

Довольно речи, пора к делу!

Такой функции нет ни в sass (scss) ни в less. Пишем сами, назовём lighter. Она простая и алгоритм заключается в том, чтобы hex привести в формату rgb, а там можно легко манипулировать цветом прибавляя или отнимая по 16.

У каждого цвета всего 16 тонов и 16 полутонов (от 0 до f из 16-тиричной системы). Перемножая их получится 255, начиная с 0. Теперь понятно, почему число 6.25% является процентом одного тона, ведь 100% / 16 = 6.25%

Функция осветления на один тон в SASS (SCSS)

// SASS
@function lighter($color, $tone)
  $adjust: 16*$tone
  @return adjust-color($color, $red: $adjust, $green: $adjust, $blue: $adjust)

// SCSS
@function lighter($color, $tone) {
  $adjust: 16*$tone;
  @return adjust-color($color, $red: $adjust, $green: $adjust, $blue: $adjust);
}

Функция затемнения на один тон в SASS (SCSS)

// SASS
@function darker($color, $tone)
  $adjust: -16*$tone
  @return adjust-color($color, $red: $adjust, $green: $adjust, $blue: $adjust)


// SCSS
@function darker($color, $tone) {
  $adjust: -16*$tone;
  @return adjust-color($color, $red: $adjust, $green: $adjust, $blue: $adjust);
}

Здесь,

  • $color - цвет, который необходимо затемнить или осветлить
  • $tone - количество тонов, на которые необходимо осветлить или затемнить от 0 до 17

Пример работы с функцией осветления, затемнения цвета на один или несколько тонов.

// SASS
body
  color: lighter(#889fa8, 1) // => #98afb8

// SCSS
body {
  color: lighter(#889fa8, 1); // => #98afb8
}

Обратите внимание, что:

lighter(#e0eff1, 1) // => #f0ffff
lighter(#e0eff1, 2) // => #ffffff

Т.е. полутон, тоже меняется, но только после достижения тоном максимального или минимального значения.

Напоследок

Другой подход к этой задаче: комбинируем функции в одну с дополнительным параметром.

// SASS
@function tone($color, $tone: 1, $dir: up)
  $adjust: if($dir == up, 16, -16) * $tone
  @return adjust-color($color, $red: $adjust, $green: $adjust, $blue: $adjust)

// Примеры работы в SASS
color: tone(#889fa8)           // => #98afb8
color: tone(#889fa8, 1)        // => #98afb8
color: tone(#889fa8, 1, up)    // => #98afb8
color: tone(#889fa8, 2)        // => #a8bfc8
color: tone(#889fa8, 1, down)  // => #788f98
color: tone(#889fa8, 2, down)  // => #687f88

// SCSS
@function tone($color, $tone: 1, $dir: up) {
  $adjust: if($dir == up, 16, -16) * $tone;
  @return adjust-color($color, $red: $adjust, $green: $adjust, $blue: $adjust);
}

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

 

UPD. 28.11.2017

LESS

К сожалению, в less можно выполнить такую задачу только дополнительным параметром.

В less нет возможности создавать функции с возвращаемым значением.
.tone(@property, @colors, @tones: 1, @value: color) {
  @step: 16;
  @red: red(@colors) + (@step * @tones);
  @green: green(@colors) + (@step * @tones);
  @blue: blue(@colors) + (@step * @tones);
  @color: rgb(@red, @green, @blue);
  @{property}: @@value;
}

.lighter(@property, @color, @tones: 1) {
  .tone(@property, @color, @tones);
}

.darker(@property, @colors, @tones: 1) {
  .tone(@property, @colors, @tones*(-1));
}

Использование такого миксина будет выглядеть так

a {
  .lighter(color, #000, 3); // => #303030
}

Другие посты