CSS预处理器技术已经非常的成熟,而且也涌现出了很多种不同的CSS预处理器语言,而我们接触最多的就是Scss,Stylus,Less。如此之多的CSS预处理器 其终究目的是使得CSS开发更灵活和更强大

简介

CSS 预处理器技术已经非常的成熟,而且也涌现出了越来越多的 CSS 的预处理器框架。

不过这里就来谈谈最为普遍的三款 CSS 预处理器框架 不过最主要还是谈谈SassLess

定义说明

CSS预处理器

CSS 预处理器是一种语言用来为 CSS 增加一些编程的的特性,无需考虑浏览器的兼容性问题,
例如你可以在 CSS 中使用变量、简单的程序逻辑、

函数等等在编程语言中的一些基本技巧,可以让你的 CSS 更为简洁,适应性更强,代码更直观等诸多好处

通俗的将就是讲原本的CSS语言抽象出来使他具有一定的程序逻辑 也省去了中间的很多步骤

而这些预处理器无非就是集合了语法、变量、嵌套、混入(Mixin)、继承、导入、函数和操作符等方面的操作处理

Sass

Sass是一种动态样式语言,Sass语法属于缩排语法,

css比多出好些功能(如变量、嵌套、运算,混入(Mixin)、继承、颜色处理,函数等),这样也使开发者更加的容易阅读

说白了sass就是scss的严格模式 所以说他更像一门编程语言 因为他有一些诸如语言的特性

  • sass有变量和作用域 变量有全局和局部之分,并且有优先级
  • sass有函数的概念
  • 进程控制(也就是我们所说的@if @else等)
  • 数据结构 $list类型-数组 $map类型-object 其余的也有stringnumberfunction等类型

Scss

SCSSSass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。也就是说,任何标准的 CSS3

样式表都是具有相同语义的有效的 SCSS 文件。另外,SCSS 还能识别大部分 CSS hacks(一些 CSS 小技巧)和特定于浏览器的语法

Scss 和 Sass 的区别

SassSCSS 也可以说是同一种的,我们平时都称之为 Sass,两者之间不同之处有以下两点:

首先文件扩展名不同,Sass 是以".sass"后缀为扩展名,而 SCSS 是以".scss"后缀为扩展名

语法书写方式不同,Sass 是以严格的缩进式语法规则来书写(这也是之前我们所提到的)

不带大括号({})和分号(;),而 SCSS 的语法书写和我们的 CSS 语法书写方式非常类似。

我们平常所说的Sass文件基本都是以.scss文件 这样也是避免 sass 后缀名的严格格式要求报错。

举个例子来说的话:

Sass语法
$primary-color: #eee //定义变量

body
  color: $primary-color
Scss语法
$primary-color: #eee;

body {
  color: $primary-color;
}

最后编译的结果是:

body {
  color: #eee;
}

Less

SASS的影响较大,但又使用CSS的语法,让大部分开发者和设计师更容易上手,在ruby社区之外支持者远超过SASS

其缺点是比起SASS来,可编程功能不够,不过优点是简单和兼容CSS,个人实际开发的话会更容易上手

反过来也影响了SASS演变到了SCSS的时代 这也就是为什么现在Scss完全兼容Css3的原因了

Stylus

2010年产生,来自Node.js社区,主要用来给Node项目进行CSS预处理支持

在此社区之内有一定支持者,在广泛的意义上人气还完全不如SASSLESS

简单语法使用

1.变量

你可以在 CSS 预处理器中声明变量,并在整个样式单中使用,支持任何类型的变量
例如颜色、数值(不管是否包括单位)、文本。然后你可以任意引用该变量

不同的是Sass允许使用变量,所有变量以$开头

$mainColor: #0982c1;
$siteWidth: 1024px;
$borderStyle: dotted;
 
body 
  color: $mainColor;
  border: 1px $borderStyle $mainColor;
  max-width: $siteWidth;

Less则以@开始

@mainColor: #0982c1;
@siteWidth: 1024px;
@borderStyle: dotted;
 
body {
  color: @mainColor;
  border: 1px @borderStyle @mainColor;
  max-width: @siteWidth;
}

所以最后的编译结果就是:

body {
  color: #0982c1;
  border: 1px dotted #0982c1;
  max-width: 1024px;
}

可以体会得到的是变量的使用 就和一个全局变量的作用差不多 我们在需要修改颜色等样式的值时只需要去修改定义的值就好了

当然变量也是有作用域的 就如上面的是声明在规则块定义外的 如果定义在css规则块内,那么该变量只能在此规则块内使用

$nav-color: #F90;
nav {
  $width: 100px;
  width: $width;
  color: $nav-color;
}

//编译后

nav {
  width: 100px;
  color: #F90;
}

这里的$width就只能在nav这个规则快里使用

2.嵌套

这个也是我认为非常方便的一个地方 很多时候样式的定义需要一堆的父级类名的限制 最后的结果呢一个样式却堆成很长 又很难后期维护

特别的在我们需要在CSS中相同的 parent 引用多个元素,这将是非常乏味的,你需要一遍又一遍地写 parent。例如

section {
  margin: 10px;
}
section nav {
  height: 25px;
}
section nav a {
  color: #0982C1;
}
section nav a:hover {
  text-decoration: underline;
}

这时我们在Css预处理器里可以这样定义

section {
  margin: 10px;
 
  nav {
    height: 25px;
 
    a {
      color: #0982C1;
 
      &:hover {
        text-decoration: underline;
      }
    }
  }
}

这里最后的编译结果和上面的是一样的 最后的结果也一目了然了 下面的定义我们很清楚的看到父级与子级的关系 修改起来也十分方便

这里使用了一个父选择器的标识符&

当然还有就是群组选择器的嵌套 举例来说的话就是:

.container {
  h1, h2, h3 {margin-bottom: .8em}
}

当然这样是等价于:

.container h1, .container h2, .container h3 { margin-bottom: .8em }

这样其实也很容易明白

对于选择器的使用其实还有诸如 子组合选择器和同层组合选择器:>、+和~ 这些在文档上都有写到 看一下就能明白了

理解起来和父选择器差不多

还有一个值得看一下的就是属性的嵌套 比如在对于border的定义

如果要反复写border-style border-width border-color以及border-*等也是非常烦人的。在预处理器中,你只需敲写一遍border

nav {
  border: {
  style: solid;
  width: 1px;
  color: #ccc;
  }
}

最后的编译结果看看也能知道就是:

nav {
  border-style: solid;
  border-width: 1px;
  border-color: #ccc;
}

3. Mixins (混合器)

Mixins 有点像是函数或者是C语言的宏,我个人更觉得更像是函数的定义 当你某段 CSS 经常需要在多个元素中使用时

你可以为这些共用的 CSS 定义在一个 Mixin,然后你只需要在需要引用这些 CSS 地方调用该 Mixin 即可

同时你可以传入你的参数 那么那块就会载入你定义在Mixins的样式代码了

使用混合器

Sass

@mixin rounded-corners {
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}

这样你就可以在需要这块代码的地方去引入

notice {
  background-color: green;
  border: 2px solid #00aa00;
  @include rounded-corners;
}

所以最终编译的结果就是

.notice {
  background-color: green;
  border: 2px solid #00aa00;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}

Less语法里

.error(@borderWidth: 2px) {
  border: @borderWidth solid #F00;
  color: #F00;
}
 
.generic-error {
  padding: 20px;
  margin: 4px;
  .error(); 
}
.login-error {
  left: 12px;
  position: absolute;
  top: 20px;
  .error(5px); 
}

当然混合器中不仅可以包含属性,也可以包含css规则,包含选择器和选择器中的属性

举例来说就是

@mixin no-bullets {
  list-style: none;
  li {
    list-style-image: none;
    list-style-type: none;
    margin-left: 0px;
  }
}

其实最后编译的道理是相同的这里就不过多展开说了

混合器传递参数

这时就更像一个function

@mixin link-colors($normal, $hover, $visited) {
  color: $normal;
  &:hover { color: $hover; }
  &:visited { color: $visited; }
}

所以接下来你在引入时需要给这个CSS函数传递必要的参数 就像这样

a {
  @include link-colors(blue, red, green);
}

而在Less里就可以这样定义

.link-colors($normal, $hover, $visited) {
  color: $normal;
  &:hover { color: $hover; }
  &:visited { color: $visited; }
}

那么调用的时候就是

a {
  .link-colors(blue, red, green);
}

两者其实都差不多 只不过表示方式不太一样而已

4. 继承

任何css规则都可以继承其他规则,几乎任何css规则也都可以被继承.

通常使用继承会让你的css美观、整洁。因为继承只会在生成css时复制选择器

.menu {
  border: 1px solid #ddd;
}
.footer {
  @extend .menu;
}

这样编译后的效果和下面的是一样的:

.menu, .footer {
  border: 1px solid #ddd;
}

这样一来.footer继承了.menu的样式定义 那么我们就可以不用使用逗号将两者分开来写了

Less里我们同样可以这样写:

.menu {
  border: 1px solid #ddd;
}
.footer {
  &:extend .menu;
}

最后编译出来的结果和之前是一样的

5. 导入

Sassimport的规则在生成css文件时就把所相关的文件导入进来了 这也就省去了额外的下载请求

使用SASS部分文件

但你在写一些不需要独立生成css文件 而只是为了引入到其他的sass文件 那么这里的sass文件也叫局部文件 因为他不要单独生成
对应的css文件 而是想结合其他的sass文件最终生成css文件

对于这样的文件有个约定就是命名以下划线开头 而当引入这个文件时就只需要提供下划线后面的文件名即可

如你想引入 themes/_night-sky.scss 这个局部文件里的变量 只需在样式表中写@import "themes/night-sky"

这里介绍一个最为常用的场景就是嵌套的引入

举例说明,有一个名为_blue-theme.scss的局部文件:

aside {
  background: blue;
  color: white;
}

如果你需要导入到css文件里 :

.blue-theme {@import "blue-theme"}

//结果跟你直接在.blue-theme选择器内写_blue-theme.scss文件的内容完全一样。
.blue-theme {
  aside {
    background: blue;
    color: #fff;
  }

Sass差不多 在Less中 如果你导入的是less文件 完全可以省略后缀名:

@import "theme"; // theme.less
@import "style.css";

总结

不管是Sass,还是LessStylus 都可以视为一种基于CSS之上的高级语言,其目的是使得CSS开发更加灵活和强大

Sass的功能比Less强大,因为他更像一门编程语言了,而Less则相对清晰明了,易于上手,对编译环境要求比较宽松。因为Sass需要Ruby环境的支持

编译比不上less.js那么直接 但我想这个并不是什么大问题

相对而言,国内前端团队使用Less的同学会略多于Sass 尽管现在很多的公司都开始转向于用Sass 而个人开发的话Less更为容易上手和方便 其实无论哪种选择 都是可以的

始终记住存在即合理 所以也没必要太纠结选择那种工具 实现自己最为满意的开发方式就ok

相关链接