一、前言

回顾计算机语言的进化史,似乎每隔几年都会诞生一个新的概念以推进计算机语言的发展。从二进制升级到指令集,从指令集再升级到编译语言。而像HTML、CSS和JavaScript这些语言都是通过浏览器来渲染的。HTML、CSS和JavaScript语言以前所未有的方式使WEB获得了巨大的成功。依靠它们,我们建立了更加庞大、更加复杂的网站,这是一件美好的事;但我们需要面对的一点是,我们要更进一步使得我们的代码易于管理和维护。其中,CSS对于易于管理和维护有着迫切的需求。CSS的简单造成了今天其代码的冗余。现在CSS准备华丽的转身了。

CSS预处理器(CSS Preprocessor),是一种构架于CSS之上的高级语言,可以通过脚本编译生成CSS代码,其目的是为了让CSS开发者的工作更简单有趣,当前已经进入了较为成熟的阶段,基本上新的WEB开发项目大都已普遍使用。

现在最主要的选择有:

  • SASS:2007年诞生,最早也是最成熟的CSS预处理器,拥有ruby社区的支持和compass这一最强大的css框架,目前受LESS影响,已经进化到了全面兼容CSS的SCSS。
  • LESS:2009年出现,受SASS的影响较大,但又使用CSS的语法,让大部分开发者和设计师更容易上手,在ruby社区之外支持者远超过SASS,其缺点是比起SASS来,可编程功能不够,不过优点是简单和兼容CSS,反过来也影响了SASS演变到了SCSS的时代,著名的Twitter Bootstrap就是采用LESS做底层语言的。
  • Stylus:2010年产生,来自Node.js社区,主要用来给Node项目进行CSS预处理支持,在此社区之内有一定支持者,在广泛的意义上人气还完全不如SASS和LESS。

以上就是CSS预编译工具的一些介绍,下面我将对SASS和LESS的使用进行讲解,并分别提供一个简单的示例。

二、LESS

1. 变量

注意,由于变量只能定义一次,其本质就是“常量”。

2. 混合(Mixin)

混合是一种将一个规则集混入另一个规则集的方法。

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

.post a {
  color: red;
  .bordered;
}

3. 嵌套规则

#header {
  color: black;
}
#header .navigation {
  font-size: 12px;
}
#header .logo {
  width: 300px;
}
#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}

还可以使用父选择器选择符:

.clearfix {
  display: block;
  zoom: 1;

  &:after {
    content: " ";
    display: block;
    font-size: 0;
    height: 0;
    clear: both;
    visibility: hidden;
  }
}

4. 运算

任何数字、颜色或者变量都可以参与运算。下面是一组案例:

@base: 5%;
@filler: @base * 2;
@other: @base + @filler;

color: #888 / 4;
background-color: @base-color + #111;
height: 100% / 2 + @filler;

5. 函数

Less 内置了多种函数用于转换颜色、处理字符串、算术运算等。这些函数在函数手册中有详细介绍。

函数的用法非常简单。下面这个例子将介绍如何将 0.5 转换为 50%,将颜色饱和度增加 5%,以及颜色亮度降低 25% 并且色相值增加 8 等用法:

@base: #f04615;
@width: 0.5;

.class {
  width: percentage(@width); // returns `50%`
  color: saturate(@base, 5%);
  background-color: spin(lighten(@base, 25%), 8);
}

6. 命名空间和访问器

#bundle {
  .button {
    display: block;
    border: 1px solid black;
    background-color: grey;
    &:hover {
      background-color: white
    }
  }
  .tab { ... }
  .citation { ... }
}

使用方法:

#header a {
  color: orange;
  #bundle > .button;
}

7. 作用域

Less中的作用域和其他语言的类似,如果在本身的作用域中找不到变量,将会从其父作用域中查找。

@var: red;

#page {
  @var: white;
  #header {
    color: @var; // white
  }
}

变量和混合不必在使用前声明,也可以放在后面:

@var: red;

#page {
  #header {
    color: @var; // white
  }
  @var: white;
}

8. 注释

/* 一个注释块
style comment! */
@var: red;

// 这一行被注释掉了!
@var: white;

9. 导入

你可以导入一个 .less 文件,此文件中的所有变量就可以全部使用了。如果导入的文件是 .less 扩展名,则可以将扩展名省略掉:

@import "library"; // library.less
@import "typo.css";

10. 其他

Mixin Guards、CSS Guards、Loop、Merge、函数式Mixin

三、SASS

1. 变量

$font-stack:    Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}

2. 嵌套

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

属性嵌套:

$fontsize: 12px
.speaker
  .name
    font:
      weight: bold
      size: $fontsize + 10px
  .position
    font:
      size: $fontsize 

3. 分离

可以将你的样式表分隔成很多个单独的文件。然后,你可以在主样式文件中通过@import引入你所需要的.scss文件。

4. 导入

// _reset.scss

html,
body,
ul,
ol {
   margin: 0;
  padding: 0;
}
/* base.scss */

@import 'reset';

body {
  font-size: 100% Helvetica, sans-serif;
  background-color: #efefef;
}

5. 混合(Mixins)

@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
     -moz-border-radius: $radius;
      -ms-border-radius: $radius;
          border-radius: $radius;
}

.box { @include border-radius(10px); }

6. 扩展和继承

.message {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  @extend .message;
  border-color: green;
}

.error {
  @extend .message;
  border-color: red;
}

.warning {
  @extend .message;
  border-color: yellow;
}

7. 运算

.container { width: 100%; }

article[role="main"] {
  float: left;
  width: 600px / 960px * 100%;
}

aside[role="complimentary"] {
  float: right;
  width: 300px / 960px * 100%;
}

四、简单示例