英文原文:http://net.tutsplus.com/tutorials/html-css-techniques/sass-vs-less-vs-stylus-a-preprocessor-shootoutphp
中文译文:http://www.w3cplus.com/css/sass-vs-less-vs-stylus-a-preprocessor-shootout.htmlcss
本文根据Johnathan Croom的《Sass vs. LESS vs. Stylus: Preprocessor Shootout》所译,整个译文带有咱们本身的理解与思想,若是译得很差或不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://net.tutsplus.com/tutorials/html-css-techniques/sass-vs-less-vs-stylus-a-preprocessor-shootout/,以及做者相关信息html
——做者:Johnathan Croom前端
——译者:大漠node
发挥CSS预处器的做用是一种颇有挑战性的事情。CSS预处器有不一样的语言,有不一样的语法和功能。css3
在这篇文章中,咱们将介绍三种不一样CSS预处器的蛮量、功能以及他们的好处——Sass、LESS和Stylusgit
介绍
CSS预处理器是一种语言,用来编写一些CSS的特性,并且无需考虑浏览器兼容性的问题。他们经过编译的代码编写成通常的CSS,不要在停留在石器时代了。CSS预处器有成千上万的特性,在本文中咱们将一一介绍。让咱们开始。github
语法
在使用CSS预处器以前最重要的是对语法的理解,幸运的是,这三种CSS预处器的语法和CSS都差很少。web
Sass和LESS
Sass和LESS都使用的是标准的CSS语法。这使用CSS预处器很是容易的将预处器代码转换成CSS代码。默认Sass使用“.scss”扩展名,而LESS使用“.less”扩展名。Sass和LESS基本设置能够像下面所示:sql
/* style.scss 或者 style.less */
h1 { color: #0982C1; }
正如你所看到的,在Sass和LESS样式中,这样的代码是在简单不过的了。
重要的一点是,Sass也同时支持老的语法,就是不使用花括号和分号,并且文件使用“.sass”扩展名,他的语法相似于:
/* style.sass */
h1
color: #0982c1
Stylus
Stylus的语法花样多一些,它使用“.styl”的扩展名,Stylus也接受标准的CSS语法,可是他也接受不带花括号和分号的语法,以下所示:
/* style.styl */
h1 { color: #0982C1; } /* 省略花括号 */ h1 color: #0982C1; /* 省略花括号和分号 */ h1 color #0982C1
你也能够在同一个样式单中使用不一样的变量,例以下面的写法也不会报错:
h1 {
color #0982c1
}
h2
font-size: 1.2em
变量(Variables)
你能够在CSS预处理器中声明变量,并在整个样式表中使用。CSS预处理器支持任何变量(例如:颜色、数值(不论是否包括单位)、文本)。而后你能够在任意地方引用变量。
Sass
Sass声明变量必须是“$”开头,后面紧跟变量名和变量值,并且变量名和变量值须要使用冒号(:)隔开。就像CSS属性同样:
$mainColor: #0982c1; $siteWidth: 1024px; $borderStyle: dotted; body { color: $mainColor; border: 1px $borderStyle $mainColor; max-width: $siteWidth; }
LESS
LESS声明变量和Sass声明变量同样,惟一区别是变量名前面使用是的“@”字符:
@mainColor: #0982c1; @siteWidth: 1024px; @borderStyle: dotted; body { color: @mainColor; border: 1px @borderStyle @mainColor; max-width: @siteWidth; }
Stylus
Stylus声明变量没有任何限定,你可使用"$"符号开始。结尾的分号(;)无关紧要,但变量名和变量值之间的等号(=)是须要的。有一点须要注意的是,若是咱们使用"@"符号开头来声明(0.22.4)变量,Stylus会进行编译,但其对应的值并不会赋值给变量。换句话说,在Stylus中不要使用“@”符号开头声明变量。
mainColor = #0982c1
siteWidth = 1024px
$borderStyle = dotted body color mainColor border 1px $borderStyle mainColor max-width siteWidth
转译出来的CSS
上面的代码都将转译成相同的CSS。你能够想像一下,变量的做用有多大。咱们不须要为了修改一个颜色而输入许屡次,也不须要为了修改一个宽度去到找寻找他.(咱们只须要修改定义好的变量,修改一次就足够).下面是转译过来的CSS代码:
body { color: #0982c1; border: 1px dotted #0982c1; max-width: 1024px; }
嵌套(Nesting)
若是咱们在CSS中多个元素有一个相同的父元素,那么写样式会变得很乏味,咱们须要一遍一遍的在每一个元素前写这个父元素.
section { margin: 10px; } section nav { height: 25px; } section nav a { color: #0982C1; } section nav a:hover { text-decoration: underline; }
相反,使用CSS预处理器,咱们能够在父元素的花括号({})写这些元素。同时可使用“&”符号来引用父选择器。
Sass、LESS和Stylus
对于嵌套选择器来讲,三个CSS预处器都具备相同的语法:
section {
margin: 10px; nav { height: 25px; a { color: #0982C1; &:hover { text-decoration: underline; } } } }
转译出来的CSS
上面的预处器转译出来的CSS代码。和咱们开始展现的CSS代码是相同的。很是的方便吧!
section { margin: 10px; } section nav { height: 25px; } section nav a { color: #0982C1; } section nav a:hover { text-decoration: underline; }
混合(Mixins)
Mixins是预处器中的函数。平时你在写样式时确定有碰到过,某段CSS样式常常要用到多个元素中,这样你就须要重复的写屡次。在CSS预处器中,你能够为这些公用的CSS样式定义一个Mixin,而后在你CSS须要使用这些样式的地方,直接调用你定义好的Mixin。这是一个很是有用的特性。Mixins是一个公认的选择器,还能够在Mixins中定义变量或者是默认参数。
Sass
/* Sass定义了一个名叫error的mixin,这个error设置了一个参数“$borderWidth”,在没特别定义外,这个参数的值是默认值2px*/
@mixin error($borderWidth: 2px) { border: $borderWidth solid #F00; color: #F00; } .generic-error { padding: 20px; margin: 4px; @include error(); /* 调用error mixins */ } .login-error { left: 12px; position: absolute; top: 20px; @include error(5px); /* 调用error mixins,并将参数$borderWidth的值指定为5px*/ }
LESS
/* LESS 定义了一个名叫error的mixin,这个error设置了一个参数“$borderWidth”,在没特别定义外,这个参数的值是默认值2px */ .error(@borderWidth: 2px) { border: @borderWidth solid #F00; color: #F00; } .generic-error { padding: 20px; margin: 4px; .error(); /* 调用error mixins */ } .login-error { left: 12px; position: absolute; top: 20px; .error(5px); /* 调用error mixins,并将参数$borderWidth的值指定为5px */ }
Stylus
/* Stylus 定义了一个名叫error的mixin,这个error设置了一个参数“$borderWidth”,在没特别定义外,这个参数的值是默认值2px */
error(borderWidth= 2px) { border: borderWidth solid #F00; color: #F00; } .generic-error { padding: 20px; margin: 4px; error(); /* 调用error mixins */ } .login-error { left: 12px; position: absolute; top: 20px; error(5px); /* 调用error mixins,并将参数$borderWidth的值指定为5px */ }
转译出来的CSS
上面三种CSS预处器转译出来的CSS代码都是同样的
.generic-error { padding: 20px; margin: 4px; border: 2px solid #f00; color: #f00; } .login-error { left: 12px; position: absolute; top: 20px; border: 5px solid #f00; color: #f00; }
Mixins在三种预处器中都有所不一样:
- Sass:在Sass定义Mixins和LESS、Stylus有所不一样,在声明Mixins时须要使用“@mixin”,而后后面紧跟Mixins的名,他也能够定义参数,同时能够给这个参数设置一个默认值,但参数名是使用“$”符号开始,并且和参数值之间须要使用冒号(:)分开。另外在Sass中调用Mixins须要使用“@include”,而后在其后紧跟你要调用的Mixins名。
- LESS:LESS中声明Mixins和CSS定义样式很是相似,能够将Mixins当作是一个选择器,固然Mixins也能够设置参数,并给参数设置默认值。不过设置参数的变量名是使用“@”开始,一样参数和默认参数值之间须要使用冒号(:)分开。
- Stylus:Stylus和前二者也略有不一样,他能够不使用任何符号,就是直接定义Mixins名,而后在定义参数和默认值之间用等号(=)来链接。
上面只是Mixins在三个CSS预处器的简单区别,详细的还能够进入他们的官网了解,或者对比一下上面的三段代码。
—— 大漠
继承(Inheritance)
在多个元素应用相同的样式时,咱们在CSS一般都是这样写:
p,
ul, ol { /* 样式写在这 */ }
这样作很是的好,但每每咱们须要给单独元素添加另外的样式,这个时候咱们就须要把其中选择器单独出来写样式,这样一回来咱们维护样式就至关的麻烦。为了应对这个问题,CSS预处理器能够从一个选择继承另外一个选择器下的全部样式。
Sass和Stylus
.block { margin: 10px 5px; padding: 2px; } p { @extend .block; /* 继承.block全部样式 */ border: 1px solid #EEE; } ul, ol { @extend .block; /* 继承.block全部样式 */ color: #333; text-transform: uppercase; }
上面的代码转译成CSS
.block, p, ul, ol { margin: 10px 5px; padding: 2px; } p { border: 1px solid #EEE; } ul, ol { color: #333; text-transform: uppercase; }
LESS
LESS支持的继承和Sass与Stylus不同,他不是在选择器上继承,而是将Mixins中的样式嵌套到每一个选择器里面。这种方法的缺点就是在每一个选择器中会有重复的样式产生。
.block { margin: 10px 5px; padding: 2px; } p { .block; /* 继承 '.block'中的样式 */ border: 1px solid #EEE; } ul, ol { .block; /*继承'.block' 中的样式*/ color: #333; text-transform: uppercase; }
转译出来的CSS代码
.block { margin: 10px 5px; padding: 2px; } p { margin: 10px 5px; padding: 2px; border: 1px solid #EEE; } ul, ol { margin: 10px 5px; padding: 2px; color: #333; text-transform: uppercase; }
正如所看到的,上面的代码“.block”的样式将会被插入到相应的你要继承的选择器中,但须要注意是的优先级的问题。
导入(import)
在CSS中,并不喜欢用@import来导入样式,由于这样的作法会增长HTTP的请求。可是在CSS预处理器中的导入(@import)规则和CSS的有所不一样,它只是在语义上导入不一样的文件,但最终结果是生成一个CSS文件。若是你是经过“@import 'file.css'”导入“file.css”样式文件,那效果跟普通CSS导入样式文件同样。注意:导入文件中定义了变量、混合等信息也将会被引入到主样式文件中,所以须要避免他们的相互冲突。
Sass、LESS和Stylus
/* file.{type} */
body { background: #EEE; }
@import "reset.css"; @import "file.{type}"; p { background: #0982C1; }
转译出来的CSS
@import "reset.css"; body { background: #EEE; } p { background: #0982C1; }
颜色函数
颜色函数是CSS预处里器中内置的颜色函数功能,这些功能能够对颜色值进行处理,例如颜色的变亮、变暗、渐变颜色等处理十分的方便。
Sass
lighten($color, 10%); /* 返回的颜色在$color基础上变亮10% */ darken($color, 10%); /* 返回的颜色在$color基础上变暗10% */ saturate($color, 10%); /* 返回的颜色在$color基础上饱和度增长10% */ desaturate($color, 10%); /* 返回的颜色在$color基础上饱和度减小10% */ grayscale($color); /* 返回$color的灰度色*/ complement($color); /* returns complement color of $color */ invert($color); /* 返回$color的反相色 */ mix($color1, $color2, 50%); /* mix $color1 with $color2 with a weight of 50% */
这只是Sass中颜色函数的一个简单列表,更多详细的介绍你能够阅读Sass文档。
颜色函数何以运用到任何一个元素上都是一个有颜色的CSS属性,下面是一个简单的例子:
$color: #0982C1; h1 { background: $color; border: 3px solid darken($color, 50%);/*边框颜色在$color的基础上变暗50%*/ }
LESS
lighten(@color, 10%); /* 返回的颜色在@color基础上变亮10% */ darken(@color, 10%); /* 返回的颜色在@color基础上变暗10%*/ saturate(@color, 10%); /* 返回的颜色在@color基础上饱和度增长10% */ desaturate(@color, 10%); /* 返回的颜色在@color基础上饱和度下降10%*/ spin(@color, 10); /* 返回的颜色在@color基础上色调增长10 */ spin(@color, -10); /* 返回的颜色在@color基础上色调减小10 */ mix(@color1, @color2); /* 返回的颜色是@color1和@color2二者的混合色 */
LESS的完整颜色函数功能,请阅读LESS 文档
下面是LESS中如何使用一个颜色函数的简单例子
@color: #0982C1; h1 { background: @color; border: 3px solid darken(@color, 50%); }
Stylus
lighten(color, 10%); /* 返回的颜色在'color'基础上变亮10% */ darken(color, 10%); /* 返回的颜色在'color'基础上变暗10% */ saturate(color, 10%); /* 返回的颜色在'color'基础上饱和度增长10% */ desaturate(color, 10%); /* 返回的颜色在'color'基础上饱和度下降10% */
有关于Stylus的颜色函数介绍,请阅读Stylus文档
下面是Stylus颜色函数的一个简单实例
color = #0982C1
h1
background color
border 3px solid darken(color, 50%)
运算符(Operations)
咱们都向往在CSS作一些运算,可是没法实现。可是在CSS预处器中对样式作一些运算是一点问题都没有了,例如:
Sass、LESS和Stylus
body { margin: (14px/2); top: 50px + 100px; right: 100px - 50px; left: 10 * 10; }
实际运用
咱们介绍了CSS预处理器各方面的特性,但咱们尚未实战过。下面是CSS预处理器应用的一些例子。
属性前缀
这是宣传CSS预处理器的缘由之一,而且是一个很好的理由,这样能够节省大量的时间和汗水。建立一个minxin来处理浏览器的前缀问题是一个很简单的,而且能节省大量的重复工做和痛苦的代码编辑,咱们来看一个例子。
Sass
@mixin border-radius($values) { -webkit-border-radius: $values; -moz-border-radius: $values; border-radius: $values; } div { @include border-radius(10px); }
LESS
.border-radius(@values) {
-webkit-border-radius: @values; -moz-border-radius: @values; border-radius: @values; } div { .border-radius(10px); }
Stylus
border-radius(values) {
-webkit-border-radius: values; -moz-border-radius: values; border-radius: values; } div { border-radius(10px); }
转译出来的CSS
div { -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; }
浏览器前缀的问题,主要是针对于CSS3属性的运用,众所周知,CSS3的属性有并非全部浏览器都支持属性的标准语法,所以在实际运用中时,不得不加上各浏览器的前缀来识别,这对于咱们前端人员来讲是多么苦逼的一件事情。虽然有prefix这样的js脚本帮咱们解决,但对于怎么说也须要额外添加一个脚本文件,这对于追求完美的同窗来讲可能完法接受。
如今多了一种解决方案,就是使用CSS预处理器,如上面圆角的实现方法,这样减轻了咱们不少工做量。若是你对这一部分实现方法感兴趣,不仿花时间阅读一下如下源码:
- cssmixins:由 Matthew Wagerfield整理的CSS3属性在三种预处理器中的Mixins的定义: LESS、 Sass (还有 SCSS)和 Stylus
- LESS-Prefixer
- Custom User @mixins
—— 大漠
3D文本
使用text-shadow的多重属性制做 3D文本效果是一个很好的方法。惟一麻烦的问题就是修改文本阴影的颜色。若是咱们使用Mixin和颜色函数的话,实现3D文本效果就很是的轻松了,咱们来尝试一下。
Sass
@mixin text3d($color) { color: $color; text-shadow: 1px 1px 0px darken($color, 5%), 2px 2px 0px darken($color, 10%), 3px 3px 0px darken($color, 15%), 4px 4px 0px darken($color, 20%), 4px 4px 2px #000; } h1 { font-size: 32pt; @include text3d(#0982c1); }
LESS
.text3d(@color) {
color: @color; text-shadow: 1px 1px 0px darken(@color, 5%), 2px 2px 0px darken(@color, 10%), 3px 3px 0px darken(@color, 15%), 4px 4px 0px darken(@color, 20%), 4px 4px 2px #000; } span { font-size: 32pt; .text3d(#0982c1); }
Stylus
text3d(color)
color: color
text-shadow: 1px 1px 0px darken(color, 5%), 2px 2px 0px darken(color, 10%), 3px 3px 0px darken(color, 15%), 4px 4px 0px darken(color, 20%), 4px 4px 2px #000 span font-size: 32pt text3d(#0982c1)
在Stylus中text-shadow的样式写在一行,是由于stylus中省略了花括号({})和分号(;)。
上面三种方法实现的效果都是同样的:
列(Columns)
我第一次接触CSS预处理器的时候,我就想着使用数字或者变量进行运算。使用数值和变量运算,能够很方便的实现适应屏幕大小的布局处理。只须要定义宽度的变量,咱们就能够很方便的根据需求实现布局。下面的例子就是这么作的。
Sass
$siteWidth: 1024px; $gutterWidth: 20px; $sidebarWidth: 300px; body { margin: 0 auto; width: $siteWidth; } .content { float: left; width: $siteWidth - ($sidebarWidth+$gutterWidth); } .sidebar { float: left; margin-left: $gutterWidth; width: $sidebarWidth; }
LESS
@siteWidth: 1024px; @gutterWidth: 20px; @sidebarWidth: 300px; body { margin: 0 auto; width: @siteWidth; } .content { float: left; width: @siteWidth - (@sidebarWidth+@gutterWidth); } .sidebar { float: left; margin-left: @gutterWidth; width: @sidebarWidth; }
Stylus
siteWidth = 1024px;
gutterWidth = 20px; sidebarWidth = 300px; body { margin: 0 auto; width: siteWidth; } .content { float: left; width: siteWidth - (sidebarWidth+gutterWidth); } .sidebar { float: left; margin-left: gutterWidth; width: sidebarWidth; }
转译出来的CSS
body { margin: 0 auto; width: 1024px; } .content { float: left; width: 704px; } .sidebar { float: left; margin-left: 20px; width: 300px; }
明显的怪癖
使用CSS预处器都是有些怪癖的,我须要去寻找一些这样的人,若是你真的对这些感兴趣,你能够去搜索他们以及相关的文档,由于在你使用CSS预处理器很是有帮助。
错误报告
若是你常用CSS,你会发现很难找到CSS中出错的地方。也许你也会像我同样,花一下午的时间,发了疯的注解每行样式代码来寻找这个CSS错误。
CSS预处理器就轻松多了,他会给你报告错误。你能够阅读这篇文章,学习如何让CSS预处理器报告错误。
注释(Comments)
CSS预处理器支持“/* */”这样的多行注释方式(相似于CSS的注释方式),也支持“//”单行注释方式(相似于Javascript的注释方式)。
须要注意,若是你要压缩文件,你须要把全部注释都删除。
总结
三个预处理器咱们都覆盖了(Sass、LESS和Stylus),都以他们独特的特性完成了相同的效果。这样让开发人员更好的选择适合本身的CSS预处理器,从而更好的维护本身的代码,提升开发效率。
虽然不是开发的要求,但CSS预处理器能够节省大量的时间,而且有一些很是有用的功能。
我鼓励你们尽量的尝试使用CSS预处理器,这样就能够有效的让你选择一个你最喜欢的和知道他为何是受人青睐的。若是你尚未尝试过使用CSS预处理器来写你的CSS样式,我强烈建议你尝试一下。
若是你有最喜欢的CSS预处理器的功能,我并无提到的,但愿在下面的评论中与咱们分享。
译者手语:整个翻译依照原文线路进行,并在翻译过程略加了我的对技术的理解。若是翻译有不对之处,还烦请同行朋友指点。谢谢!