关于Sass颜色函数的尝试

1,156 阅读2分钟

Sass内置模块包含了很多实用的函数,可以为我们提高编程效率。其中sass:color颜色模块提供了很多神奇有趣的函数,让我们可以很轻松地调节颜色。下面尝试通过具体的例子来说明不同函数的实战应用

mix

用法

mix($color1, $color2, $weight: 50%) //=> color 

mix将两个颜色值混合并且返回一个新的颜色值。 $weight越大,$color1占比越大;反之$color2占比越大。

应用

日常开发中,UI小姐姐提供了一份按钮的ui规范。

mix.png

我们先写下基础按钮的样式

.btn {
  background: #fff;
}
.btn-warining {
  background: linear-gradient(0deg, #ff6f50 0, #ff3e3e 100%);
}
.btn-primary {
  background: linear-gradient(0deg, #0056ff 0, #007eff 100%);
}

好家伙,还是渐变色的。现在需要给:hover添加10%的黑色混合,给:active添加30%的黑色混合。如果我们都一一通过取色器把混合后的对应颜色取出来,这也太麻烦了吧,并且日后也不便于维护啊。

.btn-warning {
  background: linear-gradient(0deg, #ff6f50 0, #ff3e3e 100%);
  &:hover {
    background: linear-gradient(0deg, #e66448 0, #e63838 100%);
  }
  &:active {
    background: linear-gradient(0deg, #b34e38 0, #b32b2b 100%);
  }
}

我的双手告诉我不能这样做,那能靠谁,当然是Sass的mix函数,给力

@function shade($color, $weight) {
  @return mix(black, $color, $weight);
}

.btn-warning {
  $topBg: #ff6f50;
  $bottomBg: #ff3e3e;
  background: linear-gradient(0deg, $topBg 0, $bottomBg 100%);
  &:hover {
    background: linear-gradient(0deg, shade($topBg, 10%) 0, shade($bottomBg, 10%) 100%);
  }
  &:active {
    background: linear-gradient(0deg, shade($topBg, 30%) 0, shade($bottomBg, 30%) 100%);
  }
}

还没完,还有.btn-primary样式没写。而且其实很多代码是重复的,我们可以进一步封装一下。先把统一的渐变色写成mixins

@mixin linearGradient($top, $bottom) {
  background: linear-gradient(0deg, $top 0, $bottom 100%);
}

把按钮主题色用map结构存储

$buttonTheme: (
  warning: (
    topBg: #ff6f50,
    bottomBg: #ff3e3e,
  ),
  primary: (
    topBg: #0056ff,
    bottomBg: #007eff,
  ),
);

最后

.btn {
  // 省略其他样式

  @each $name, $cluster in $buttonTheme {
    $topBg: map.get($cluster, "topBg");
    $bottomBg: map.get($cluster, "bottomBg");

    &-#{$name} {
      @include linearGradient($topBg, $bottomBg);
      color: #fff;
      // 省略其他样式
      
      &:hover {
        @include linearGradient(shade($topBg, 10%), shade($bottomBg, 10%));
      }
      &:active {
        @include linearGradient(shade($topBg, 30%), shade($bottomBg, 30%));
      }
    }
  }
}

至此完成封装。

最后我们再回顾下mix函数,常见使用方式就是封装成shade(遮阴)和tint(增亮)的函数。例如bootstrap里的代码块

// Tint a color: mix a color with white
@function tint-color($color, $weight) {
  @return mix(white, $color, $weight);
}

// Shade a color: mix a color with black
@function shade-color($color, $weight) {
  @return mix(black, $color, $weight);
}

// Shade the color if the weight is positive, else tint it
@function shift-color($color, $weight) {
  @return if($weight > 0, shade-color($color, $weight), tint-color($color, -$weight));
}

简单使用

@debug shift-color($color, 10%);  // 遮阴
@debug shift-color($color, -10%); // 增亮

lighten和darken

用法

darken($color, $amount)

关于颜色变浅函数和加深函数的例子,同样是可以用伪元素上。如果UI小姐姐没有给出hover效果规范的话,我们可以自己快速简单使用。

a {
  $white: #fefefe;
  color: $white;

  &:hover,
  &:focus {
    color: darken($white, 10%);
  }
}

rgba

它用法其实和原生的一样,只是Sass对其进行了加强

比如

background: rgba(#333, .5)

原生rgba可做不到这样,编译后为

background: rgba(51, 51, 51, 0.5);

还可以用传入变量

$black: #000;
$modal-backdrop-bg: rgba($black, .5);
$loading-backdrop-bg: rgba($black, .85);

我们只需要定义好$black变量,其他基于这个变量的颜色透明度可以随意切换,减少了更改成本。

额外补充下,假如我们项目已经用上了原生的css变量,例如

:root {
  --black: #000;
}

.modal-backdrop {
  background: rgba(var(--black), .5);
}

这样会有问题,那么我们得老老实实多定义一个变量,或者我们不使用变量

:root {
  --black: #000;
  --modal-backdrop-bg: rgba(0, 0, 0, .5);
}

.modal-backdrop {
  background: var(--modal-backdrop-bg);
}

又或者我们将--black不用hex值的写法

:root {
  --black: 0, 0, 0;
}

.modal-backdrop {
  background: var(--black, .5);
}

这样也是可以。

opacify和transparentize

这两个函数可以让原本是rgba值变得更加不透明或者更加透明,例如我们会用到的场景

.tag {
  $background: rgba(#ff9830, .1);
  background: $background;
  border: 1px solid opacify($background, 0.2);
}

编译后

.tag {
  background: rgba(255, 152, 48, 0.1);
  border: 1px solid rgba(255, 152, 48, 0.3);
}

总结

Sass内置颜色函数还有很多,adjustadjust-huealphacomplementdesaturate等等,大部分日常开发中暂时用不到,这里只是列举了日常经常派得上用场的颜色函数,这次就说到这儿,下次见。