首页 > 技术文章 > CSS预处理器们

zcynine 2015-12-01 11:56 原文

CSS预处理器有很多,最早的是2006年的Less,到后来2010年的SASS,还有现在也很出名的Stylus。不过要使用它们都要使用一些工具,比如Less的话要使用Grunt或者Gulp或者Node.js,SASS要用Ruby的环境来编译。我个人对工具依赖性太强的东西并无好感,我还是喜欢只要给我一个文本编辑器和几个我已经读透了的常用的类库和框架我就能写出很多我想要的东西这样的方式。多了解一些总没坏处,So,学习吧!

 

Less

环境布置

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet/less" type="text/css" href="css/test.less" />
        <script src="js/less.js" type="text/javascript"></script>
    </head>
    <body>
        
    </body>
</html>

务必确保在 less.js 之前加载你的样式表。
如果加载多个 .less 样式表文件,每个文件都会被单独编译。因此,一个文件中所定义的任何变量、mixin 或命名空间都无法在其它文件中访问 。
注:请在服务器环境下使用!本地直接打开可能会报错!

 

变量

变量允许我们单独定义一系列通用的样式,然后在需要的时候去调用。所以在做全局样式调整的时候我们可能只需要修改几行代码就可以了。

@color: #4D926F;
.test{
    background:@color;
}

还可以把变量名当作变量

@fnord: "I am fnord.";
@var: 'fnord';
content: @@var;

解析后的结果就是,content:"I am fnord.";

混合

混合可以将一个定义好的class A轻松的引入到另一个class B中,从而简单实现class B继承class A中的所有属性。我们还可以带参数地调用,就像使用函数一样。

.rounded-corners (@radius: 5px) {
  border-radius: @radius;
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
}
.test1 {
  .rounded-corners;
}
.test2 {
  .rounded-corners(10px);
}

比如说我们经常要写到的border属性,很多时候用到的border都是一样,这个时候我们可以把border专门写成一个class,然后混合到其他class当中

.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

#menu a {
  color: #111;
  .bordered;
}
.post a {
  color: red;
  .bordered;
}

这样最后的结果就等同于

#menu a {
  color: #111;
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}
.post a {
  color: red;
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

@arguments 变量

@arguments包含了所有传递进来的参数.

.box-shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) {
  box-shadow: @arguments;
  -moz-box-shadow: @arguments;
  -webkit-box-shadow: @arguments;
}
.box-shadow(2px, 5px);

这样的结果就是

box-shadow: 2px 5px 1px #000;
  -moz-box-shadow: 2px 5px 1px #000;
  -webkit-box-shadow: 2px 5px 1px #000;

模式匹配

.class {
  .mixin(@switch, #888);
}
.mixin (dark, @color) {
  color: darken(@color, 10%);
}
.mixin (light, @color) {
  color: lighten(@color, 10%);
}
.mixin (@_, @color) {
  display: block;
}

如果运行下面这段代码

@switch: light;

.class {
  .mixin(@switch, #888);
}

将会得到

.class {
  color: #a2a2a2;
  display: block;
}

第一个混合定义并未被匹配,因为它只接受dark做为首参
第二个混合定义被成功匹配,因为它只接受light
第三个混合定义被成功匹配,因为它接受任意值

也可以匹配多个参数

.mixin (@a) {
  color: @a;
}
.mixin (@a, @b) {
  color: fade(@a, @b);
}

参数不同,函数的导向不同。

引导(导引表达式)

当我们想根据表达式进行匹配,而非根据值和参数匹配时,导引就显得非常有用。
为了尽可能地保留CSS的可声明性,LESS通过导引混合而非if/else语句来实现条件判断,因为前者已在@media query特性中被定义。

定义

.mixin (@a) when (lightness(@a) >= 50%) {
  background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) {
  background-color: white;
}
.mixin (@a) {
  color: @a;
}

when关键字用以定义一个导引序列。

调用

.class1 { .mixin(#ddd) }
.class2 { .mixin(#555) }

结果

.class1 {
  background-color: black;
  color: #ddd;
}
.class2 {
  background-color: white;
  color: #555;
}

除去关键字true以外的值都被视示布尔假:

.class {
  .truth(40); // Will not match any of the above definitions.
}

导引序列使用逗号‘,’—分割,当且仅当所有条件都符合时,才会被视为匹配成功。(其实就是---&&)

.mixin (@a) when (@a > 10), (@a < -10) { ... }

可以使用and关键字实现与条件:

.mixin (@a) when (isnumber(@a)) and (@a > 0) { ... }

使用not关键字实现非条件

.mixin (@b) when not (@b > 0) { ... }

如果想基于值的类型进行匹配,我们就可以使用is*函式:

.mixin (@a, @b: 0) when (isnumber(@b)) { ... }
.mixin (@a, @b: black) when (iscolor(@b)) { ... }

 

 

嵌套规则

我们可以在一个选择器中嵌套另一个选择器来实现继承,这样很大程度减少了代码量,并且代码看起来更加的清晰。

.test_div{
    span{
        font-size: 18px;
    }
    p{
        font-size: 12px;
        a{
            text-decoration:none;
            &:hover{
                text-decoration:underline;
            }
        }
    }
}

函数 & 运算

运算提供了加,减,乘,除操作;我们可以做属性值和颜色的运算,这样就可以实现属性值之间的复杂关系。LESS中的函数一一映射了JavaScript代码,如果你愿意的话可以操作属性值。

@the-border: 1px;
@base-color: #111;
@red:        #842210;
#header {
  color: @base-color * 3;
  border-left: @the-border;
  border-right: @the-border * 2;
}
#footer { 
  color: @base-color + #003300;
  border-color: desaturate(@red, 10%);
}

 

API

lighten(@color, 10%);     // return a color which is 10% *lighter* than @color
darken(@color, 10%);      // return a color which is 10% *darker* than @color

saturate(@color, 10%);    // return a color 10% *more* saturated than @color
desaturate(@color, 10%);  // return a color 10% *less* saturated than @color

fadein(@color, 10%);      // return a color 10% *less* transparent than @color
fadeout(@color, 10%);     // return a color 10% *more* transparent than @color
fade(@color, 50%);        // return @color with 50% transparency

spin(@color, 10);         // return a color with a 10 degree larger in hue than @color
spin(@color, -10);        // return a color with a 10 degree smaller hue than @color

mix(@color1, @color2);    // return a mix of @color1 and @color2


round(1.67); // returns `2`
ceil(2.4);   // returns `3`
floor(2.6);  // returns `2`

percentage(0.5); // returns `50%`

 

补充

字符串插入

@base-url: "http://assets.fnord.com";
background-image: url("@{base-url}/images/bg.png");

 

来源:http://www.bootcss.com/p/lesscss/#guide

 

 

SASS

1.变量

SASS允许使用变量,所有变量以$开头。

$blue : #1875e7; 
div {
  color : $blue;
}

如果变量需要镶嵌在字符串之中,就必须需要写在#{}之中

$side : left;
.rounded {
  border-#{$side}-radius: 5px;
}

2.计算

SASS允许在代码中使用算式:

body {
    margin: (14px/2);
    top: 50px + 100px;
    right: $var * 10%;
  }

3.嵌套

选择器可以嵌套

div {
    hi {
      color:red;
    }
  }

属性也可以嵌套

p {
    border: {
      color: red;
    }
  }

在嵌套的代码块内,可以使用&引用父元素。比如a:hover伪类,可以写成:

a {
    &:hover { color: #ffb3ff; }
  }

4.继承

SASS允许一个选择器,继承另一个选择器。

.class1 {
    border: 1px solid #ddd;
  }

class2要继承class1,就要使用@extend命令:

.class2 {
    @extend .class1;
    font-size:120%;
  }

5.混合

Mixin有点像C语言的宏(macro),是可以重用的代码块。

使用@mixin命令,定义一个代码块。

@mixin left {
    float: left;
    margin-left: 10px;
  }

使用@include命令,调用这个mixin。

div {
    @include left;
  }

mixin的强大之处,在于可以指定参数和缺省值。

@mixin left($value: 10px) {
    float: left;
    margin-right: $value;
  }

使用的时候,根据需要加入参数:

div {
    @include left(20px);
  }

下面是一个mixin的实例,用来生成浏览器前缀。

@mixin rounded($vert, $horz, $radius: 10px) {
    border-#{$vert}-#{$horz}-radius: $radius;
    -moz-border-radius-#{$vert}#{$horz}: $radius;
    -webkit-border-#{$vert}-#{$horz}-radius: $radius;
  }

使用的时候,可以像下面这样调用:

#navbar li { @include rounded(top, left); }
#footer { @include rounded(top, left, 5px); }

6.条件语句

@if可以用来判断:

p {
    @if 1 + 1 == 2 { border: 1px solid; }
    @if 5 < 3 { border: 2px dotted; }
  }

配套的还有@else命令:

@if lightness($color) > 30% {
    background-color: #000;
  } @else {
    background-color: #fff;
  }

7.循环

SASS支持for循环:

@for $i from 1 to 10 {
    .border-#{$i} {
      border: #{$i}px solid blue;
    }
  }

还有while循环:

$i: 6;
  @while $i > 0 {
    .item-#{$i} { width: 2em * $i; }
    $i: $i - 2;
  }

each命令,作用与for类似:

@each $member in a, b, c, d {
    .#{$member} {
      background-image: url("/image/#{$member}.jpg");
    }
  }

8.自定义函数

SASS允许用户编写自己的函数。

@function double($n) {
  @return $n * 2;
}
#sidebar {
  width: double(5px);
}

 

 

来源:http://www.ruanyifeng.com/blog/2012/06/sass.html

推荐阅读