前端开发者学堂 - fedev.cn

Sass中半透明颜色的Mixins

发布于 大漠

The Sass Way上看到一篇John W. Long写的《Mixins for Semi-Transparent Colors》文章。文章中详细的介绍了如何使用Sass来定义一个半透明颜色的mixins,觉得很有意思,认真学习之后,结合CSS中的半透明,以及Sass中的半透明做了一点总结,与大家分享。

CSS中透明实现

回想CSS中实现透明的属性主要是opacity,这个属性可以控制元素的透明度,包括其后代元素都会受到一定的影响。

opacity: .5;
filter:alpha(opaity=50);

这或许不是我们想要的效果,因为opacity属性不但是控制了颜色,而且还控制了所有元素的的透明度,是个非常BT的东东。不早期常用于制作浮层背景透明效果。

除了opacity属性之外,在CSS中控制颜色的透明的还有一个transparent值,他可以让颜色完全透明化:

color: transparent;
border-color: transparent;
background-color: transparent;

如此一来,始终无法帮助我们实现需要的半透明效果。

CSS3中半透明实现

随着CSS3的出现,实现颜色的半透明效果就变得轻松多了,其中CSS3为颜色的半透明增加了rgbahsla属性。通过这两个属性可以对任何颜色控制他的半透明效果。

color: rgba(0,0,0,.3);
border-color: hsla(20,3%,90%,.3);

Sass中颜色半透明实现

Sass给我们提供了很多有意思的颜色函数功能。可以在其他颜色的基础上计算出一个新的颜色。常见的就是使用darken()saturate()adjust-color()函数来调整颜色,最常见使用的地方就是用在按钮上,用来突出按钮的颜色和阴影。

很多Web设计师都比较喜欢使用半透明的颜色,这样可以让设计更好的容入到元素中。在Sass中使用rgba()函数就变得更加轻松与简单:

.button {
    background-color: rgba(black,.5);
}

大家都知道,CSS3中的rgba是具有四个参数的:red红色、green绿色、blue蓝色和alpha通道。而Sass中的rgba()函数仅接受两个参数,第一个参数是指定的颜色,第二个参数像CSS3中rgba属性中的alpha通道,用来控制颜色的透明度。但是Sass中rgba()函数编译出的也是使用CSS3的rgba格式,具有四个参数:

$ sass -i
>> rgba(black,.5)
rgba(0, 0, 0, 0.5)

不过使用rgba具有一定的代价,在早期的IE浏览器不识别这个属性,详情请点击这里。当浏览器访问到这个属性时,不识别的浏览器会直接忽略他。这意味着不支持的浏览器会完全透明,不过有一个方法可以避免这类现象,就是在rgba格式的前面先写一个所有浏览器都支持的颜色格式:

.button {
    background-color: #7f7f7f;
    background-color: rgba(black,.5);
}

如果你有一个颜色选择工具,例如Color Schemer Online或者说使用PSD这样的制作软件,你可以获取一个颜色的R,G,B值,或者手动修改这些值,但这并不是最好的方法。大家为何不尝试使用Sass中的mix()函数来帮助我们完成类似这样的工作呢?

.button {
    background-color: mix(black,white);// mix(black,white)-> #7f7f7f
    background-color: rgba(black,.5);
}

这样虽然完成了功能效果,但每次都需要这样操作。不过我们可以做得比这个更好。可以引入一些更强大的Sass功能,可以将一个颜色的aplha值提取出来,并将其转换成百分比,然后通过mix()函数将一个rgba()函数的颜色与一个背景色按一定的比例混合在一起,生成一个新的颜色,并将这整个功能定义为一个mixins,实现一个功能模块:

//定义一个半透明颜色mixin
@mixin semi-transparent-colors($color,$background){
    $percent: alpha($color) * 100%; //获取颜色透明度值,并转换成百分比
    $opaque: opacify($color,1); //使颜色不透明
    $solid-color: mix($opaque,$background,$percent);
    background-color: $solid-color; //设置不透明的颜色,为不支持rgba颜色的浏览器服务
    background-color: $color;//设置透明颜色,为支持rgba颜色的浏览器服务
}

简单的来看一下这个mixin

semi-transparent-colors中传了两个参数:$color$background,其中第一个参数是一个rgba()函数获取的一个颜色,如rgba(black,.5);第二个参数主要是用来和另一个颜色做mix()函数计算的颜色。

整个semi-transparent-colors的功能实现大致分为以下几个过程:

第一步,首先获取$color中的透明值,并将其转换成百分数。在这里使用了Sass中Opacity透明函数中的alpha()函数,也可以换成opacity()函数。例如:

$color: rgba(black,.5);
//在终端命令中进行测试转换
$ sass -i
>> alpha(rgba(black,.5))
0.5

得到了$color中的透明值.5,并且将其转换成一个百分值,并且将此值赋予给变量$percent

>> alpha(rgba(black,.5)) * 100%
50%

第二步也非常简单,同样是使用Opacity透明函数中的opacify($color,$amount)函数,所$amount直接设置为1,使$color函数变成一个不透明的函数,如:

$color: rgba(black,.5);
$ sass -i
>> opacify(rgba(black,.5),1)
#000000

同样将这个新得到的不透明颜色赋予给一个变量$opaque。 这个功能除了能使用opacify()函数之外,也可以使用fade-in($color,$amount)函数代替,使用方法都是一样的。

第三步,使用mix()函数,将$opauergba()函数去透明化得到的颜色)和$background颜色按$percent(取rgba()函数中颜色透明值的百分数),混合在一起得到的一个新颜色,并赋予给变量$solid-color

$solid-color: mix($opaque, $background, $percent);
>> mix(opacify(rgba(black,.5),1),white,alpha(rgba(black,.5)) * 100%)
#7f7f7f

最后一步就是将两个颜色分别定义给相应的属性上:

background-color: $solid-color; //设置不透明的颜色,为不支持rgba颜色的浏览器服务
background-color: $color;//设置透明颜色,为支持rgba颜色的浏览器服务

接下来,可以通过@include调用这个semi-transparent-colorsmixin,如:

.button {
    @include semi-transparent-colors(rgba(black,.5),white);
}

编译出来的CSS:

.button {
  background-color: #7f7f7f;
  background-color: rgba(0, 0, 0, 0.5); }

虽然这样可以轻松的使用半透明颜色,但在上面的mixin中还存有一定的缺陷,仅能将半透明颜色运用在背景颜色上,没办法使用在其他颜色属性上面。不过不用担心,我们只需要使用Sass的#{}功能,我们就可以解决上述的问题,将半透明颜色运在大部分颜色属性上,比如:colorbackground-colorborder-color等等,但类似box-shadowtext-shadow这种属性上的颜色,这种方法还不能解决。

@mixin semi-transparent-colors($attribute,$color,$background){
    $percent: alpha($color) * 100%; //获取颜色透明度值,并转换成百分比
    $opaque: opacify($color,1); //使颜色不透明
    $solid-color: mix($opaque,$background,$percent);
    #{$attribute}: $solid-color; //设置不透明的颜色,为不支持rgba颜色的浏览器服务
    #{$attribute}: $color;//设置透明颜色,为支持rgba颜色的浏览器服务
}

这个时候,我们就可以这样调用了:

.button {
    @include semi-transparent-colors("background-color",rgba(black,.5),white);
    @include semi-transparent-colors("color",rgba(white,.8),#393);
    @include semi-transparent-colors("border-color",rgba(black,.7),gray);
}

编译出来的CSS:

.button {
  background-color: #7f7f7f;
  background-color: rgba(0, 0, 0, 0.5);
  color: #d6ead6;
  color: rgba(255, 255, 255, 0.8);
  border-color: #262626;
  border-color: rgba(0, 0, 0, 0.7); }

上面主要介绍了如何使用Sass来定义一个半透明颜色的mixin,接下来,在此基础上来看一个实例,这个实例是由John W. Long写的一个按钮效果。

//定义半透明颜色
@mixin semi-transparent-colors($attribute,$color,$background){
    $percent: alpha($color) * 100%; //获取颜色透明度值,并转换成百分比
    $opaque: opacify($color,1); //使颜色不透明
    $solid-color: mix($opaque,$background,$percent);
    @if ($percent < 100%) {
        #{$attribute}: $solid-color; //设置不透明的颜色,为不支持rgba颜色的浏览器服务  
    }
    #{$attribute}: $color;//设置透明颜色,为支持rgba颜色的浏览器服务
}

//定义按钮颜色
@mixin color-button($text,$color,$background:white) {
    @include semi-transparent-colors("border-color",rgba(black,.7),$background);
    @include semi-transparent-colors("background-color",$color,$background);
    @include semi-transparent-colors("color",$text,$background);

    &:hover,
    &:focus {
        @include semi-transparent-colors("background-color",transparentize($color,.2),$background);
        @include semi-transparent-colors("color",opacify($text,1),$background);
    }   
    &:active {
        @include semi-transparent-colors("background-color",opacify($color,1),$background);
        box-shadow: none;
    }
}

//定义按钮基本样式
%button {
    border: 1px solid;
    box-shadow: inset 0 1px 0 rgba(white,.2);
  text-shadow: 0 1px 1px rgba(255, 255, 255, 1);
  font: {
      size: 14px;
      family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
  }
  padding: .4em 1em .5em;
  cursor: pointer;
}

//调用
.panel {
  width: 220px;
  padding: 50px;
  text-align: center;
  margin: 15px;
  background: gray;
  box-sizing: border-box;
  float: left;
  button{
    @extend %button;
    @include color-button(rgba(white, 0.8), rgba(black, 0.5), gray); 
  }
}
.green-panel {
  background: #393;
  button{
    @include color-button(rgba(white, 0.8), rgba(black, 0.5), #393); 
  }
}

.orange-panel {
  background: #f73;
  button{ 
    @include color-button(rgba(white, 0.8), rgba(black, 0.5), #f73); 
  }
}

编译出来的CSS:

.panel button {
  border: 1px solid;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2);
  text-shadow: 0 1px 1px white;
  font-size: 14px;
  font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
  padding: .4em 1em .5em;
  cursor: pointer; 
}

.panel {
  width: 220px;
  padding: 50px;
  text-align: center;
  margin: 15px;
  background: gray;
  box-sizing: border-box;
  float: left; 
}
.panel button {
  border-color: #262626;
  border-color: rgba(0, 0, 0, 0.7);
  background-color: #404040;
  background-color: rgba(0, 0, 0, 0.5);
  color: #e5e5e5;
  color: rgba(255, 255, 255, 0.8); 
}
.panel button:hover, 
.panel button:focus {
  background-color: #595959;
  background-color: rgba(0, 0, 0, 0.3);
  color: white; 
}
.panel button:active {
  background-color: black;
  box-shadow: none; 
}

.green-panel {
  background: #393; 
}
.green-panel button {
  border-color: #0f2d0f;
  border-color: rgba(0, 0, 0, 0.7);
  background-color: #194c19;
  background-color: rgba(0, 0, 0, 0.5);
  color: #d6ead6;
  color: rgba(255, 255, 255, 0.8); 
}
.green-panel button:hover, 
.green-panel button:focus {
  background-color: #236b23;
  background-color: rgba(0, 0, 0, 0.3);
  color: white; 
}
.green-panel button:active {
  background-color: black;
  box-shadow: none; 
}

.orange-panel {
  background: #f73;
}
.orange-panel button {
  border-color: #4c230f;
  border-color: rgba(0, 0, 0, 0.7);
  background-color: #7f3b19;
  background-color: rgba(0, 0, 0, 0.5);
  color: #ffe3d6;
  color: rgba(255, 255, 255, 0.8); 
}
.orange-panel button:hover, 
.orange-panel button:focus {
  background-color: #b25323;
  background-color: rgba(0, 0, 0, 0.3);
  color: white; 
}
.orange-panel button:active {
  background-color: black;
  box-shadow: none; 
}

注:此处展示的案例源码与John W. Long案例略有不同。

Sass基础——颜色函数

总结

在这节中主要根据John W. Long的《Mixins for Semi-Transparent Colors》文章为思路,从CSS中的透明度设置展开,引伸出CSS3的颜色透明属性,最后回到Sass中的颜色函数,并且将Sass的部分颜色函数与@mixin相结合,定制了给CSS中带有颜色的部分属性,如colorborder-colorbackground-color等轻松实现颜色半透明效果。希望这篇文章能帮助大家对Sass的颜色函数有一个更深的了解。

最后非常感谢John W. Long给我们带来这么好的教程。最后声明,文中有关于Sass实现颜色半透明功能的@mixin以及相关代码来自于《Mixins for Semi-Transparent Colors》一文。

如需转载,烦请注明出处:https://www.fedev.cn/preprocessor/mixins-for-semi-transparent-colors.html

CULTURE KINGS PARRAMATTA IS NOW HERE!