發揮CSS預處器的功能是一件很有挑戰性的事情。 CSS預處器有不同的語言,有不同的語法和功能。
在這篇文章中,我們將介紹三種不同CSS預處器的蠻量、功能以及他們的好處—— sass 、 less 和 stylus。
CSS預處理器是一種語言,用來編寫一些CSS的特性,而且無需考慮瀏覽器兼容性的問題。他們透過編譯的程式碼寫成一般的CSS,不要在停留在石器時代了。 CSS預處器有成千上萬的特性,在本文中我們將一一介紹。讓我們開始。
在使用CSS預處器之前最重要的是對語法的理解,幸運的是,這三種CSS預處器的語法和CSS都差不多。
sass和less都使用的是標準的CSS文法。這使用CSS預處器非常容易的將預處器代碼轉換成CSS代碼。預設sass使用.scss
副檔名,而less使用.less
副檔名。 sass和less基本設定可以像下面所示:
/* style.scss 或者 style.less */ h1 { color: #0982C1; }
正如你所看到的,在sass和less樣式中,這樣的程式碼是在簡單不過的了。
重要的一點是,sass也同時支持老的語法,就是不使用花括號和分號,而且文件使用.sass
擴展名,他的語法類似於:
/* style.sass */ h1 color: #0982c1
stylus的語法花樣多一些,它使用.styl
的擴展名,stylus也接受標準的CSS語法,但是他也接受不帶花括號和分號的語法,如下所示:
/* style.styl */ h1 { color: #0982C1; } /* 省略花括号 */ h1 color: #0982C1; /* 省略花括号和分号 */ h1 color #0982C1
你也可以在同一個樣式單中使用不同的變量,例如下面的寫法也不會報錯:
h1 { color #0982c1 } h2 font-size: 1.2em
你可以在CSS預處理器中宣告變數,並在整個樣式表中使用。 CSS預處理器支援任何變數(例如:顏色、數值(不管是否包含單位)、文字)。然後你可以在任意地方引用變數。
sass宣告變數必須是$
開頭,後面緊跟著變數名稱和變數值,而且變數名稱和變數值需要使用冒號:
隔開,就像CSS屬性一樣:
$mainColor: #0982c1; $siteWidth: 1024px; $borderStyle: dotted; body { color: $mainColor; border: 1px $borderStyle $mainColor; max-width: $siteWidth; }
less聲明變數和sass聲明變數一樣,唯一區別是變數名稱前面使用是的@
字元:
@mainColor: #0982c1; @siteWidth: 1024px; @borderStyle: dotted; body { color: @mainColor; border: 1px @borderStyle @mainColor; max-width: @siteWidth; }
stylus宣告變數沒有任何限定,你可以使用$
符號開始,結尾的分號;
可有可無,但變數名稱和變數值之間的等號=
是需要的。有一點要注意的是,如果我們使用@
符號開頭來宣告(0.22.4)變量,stylus會進行編譯,但其對應的值並不會賦值給變數。換句話說,在stylus中不要使用@
符號開頭宣告變數。
mainColor = #0982c1 siteWidth = 1024px $borderStyle = dotted body color mainColor border 1px $borderStyle mainColor max-width siteWidth
上面的密碼都會轉譯成相同的CSS。你可以想像一下,變數的作用有多大。我們不需要為了修改一個顏色而輸入許多次,也不需要為了修改一個寬度而到處找他。 (我們只需要修改定義好的變量,修改一次就足夠。以下是轉譯過來的CSS代碼:
body { color: #0982c1; border: 1px dotted #0982c1; max-width: 1024px; }
如果我們在CSS中多個元素有一個相同的父元素,那麼寫樣式會變得很乏味,我們需要一遍一遍的在每個元素前寫這個父元素。的花括號
{}寫這些元素,同時可以使用&
符號來引用父選擇器。嵌套選擇器來說,三個CSS預處器都具有相同的語法:<pre class="stylus">section {
margin: 10px;
}
section nav {
height: 25px;
}
section nav a {
color: #0982C1;
}
section nav a:hover {
text-decoration: underline;
}</pre>
轉譯出來的CSS
section { margin: 10px; nav { height: 25px; a { color: #0982C1; &:hover { text-decoration: underline; } } } }stylus
/* 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*/ }
Mixins在三種預處器中都有所不同:
less:less中声明Mixins和CSS定义样式非常类似,可以将Mixins看成是一个选择器,当然Mixins也可以设置参数,并给参数设置默认值。不过设置参数的变量名是使用“@”开始,同样参数和默认参数值之间需要使用冒号(:)分开。
stylus:stylus和前两者也略有不同,他可以不使用任何符号,就是直接定义Mixins名,然后在定义参数和默认值之间用等号(=)来连接。
上面只是Mixins在三个CSS预处器的简单区别,详细的还可以进入他们的官网了解,或者对比一下上面的三段代码。
在多个元素应用相同的样式时,我们在CSS通常都是这样写:
p, ul, ol { /* 样式写在这 */ }
这样做非常的好,但往往我们需要给单独元素添加另外的样式,这个时候我们就需要把其中选择器单独出来写样式,这样一回来我们维护样式就相当的麻烦。为了应对这个问题,CSS预处理器可以从一个选择继承另一个选择器下的所有样式。
.block { margin: 10px 5px; padding: 2px; } p { @extend .block; /* 继承.block所有样式 */ border: 1px solid #EEE; } ul, ol { @extend .block; /* 继承.block所有样式 */ color: #333; text-transform: uppercase; }
.block, p, ul, ol { margin: 10px 5px; padding: 2px; } p { border: 1px solid #EEE; } ul, ol { color: #333; text-transform: uppercase; }
less支持的继承和sass与stylus不一样,他不是在选择器上继承,而是将Mixins中的样式嵌套到每个选择器里面。这种方法的缺点就是在每个选择器中会有重复的样式产生。
.block { margin: 10px 5px; padding: 2px; } p { .block; /* 继承 &#39;.block&#39;中的样式 */ border: 1px solid #EEE; } ul, ol { .block; /*继承&#39;.block&#39; 中的样式*/ color: #333; text-transform: uppercase; }
.block { margin: 10px 5px; padding: 2px; } p { margin: 10px 5px; padding: 2px; /* 继承 &#39;.block&#39;中的样式 */ border: 1px solid #EEE; } ul, ol { margin: 10px 5px; padding: 2px; /*继承&#39;.block&#39; 中的样式*/ color: #333; text-transform: uppercase; }
正如所看到的,上面的代码.block
的样式将会被插入到相应的你要继承的选择器中,但需要注意是的优先级的问题。
在CSS中,并不喜欢用@import来导入样式,因为这样的做法会增加HTTP的请求。但是在CSS预处理器中的导入@import
规则和CSS的有所不同,它只是在语义上导入不同的文件,但最终结果是生成一个CSS文件。如果你是通过@import 'file.css'
导入file.css
样式文件,那效果跟普通CSS导入样式文件一样。注意:导入文件中定义了变量、混合等信息也将会被引入到主样式文件中,因此需要避免他们的相互冲突。
/* file.{type} */ body { background: #EEE; }
@import "reset.css"; @import "file.{type}"; p { background: #0982C1; }
@import "reset.css"; body { background: #EEE; } p { background: #0982C1; }
颜色函数是CSS预处里器中内置的颜色函数功能,这些功能可以对颜色值进行处理,例如颜色的变亮、变暗、渐变颜色等处理十分的方便。
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%*/ }
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%); }
lighten(color, 10%); /* 返回的颜色在&#39;color&#39;基础上变亮10% */ darken(color, 10%); /* 返回的颜色在&#39;color&#39;基础上变暗10% */ saturate(color, 10%); /* 返回的颜色在&#39;color&#39;基础上饱和度增加10% */ desaturate(color, 10%); /* 返回的颜色在&#39;color&#39;基础上饱和度降低10% */
有关于stylus的颜色函数介绍,请阅读 stylus文档。
下面是stylus颜色函数的一个简单实例
color = #0982C1 h1 background color border 3px solid darken(color, 50%)
我们都向往在CSS做一些运算,但是无法实现。但是在CSS预处器中对样式做一些运算是一点问题都没有了,例如:
body { margin: (14px/2); top: 50px + 100px; right: 100px - 50px; left: 10 * 10; }
我们介绍了CSS预处理器各方面的特性,但我们还没有实战过。下面是CSS预处理器应用的一些例子。
这是宣传CSS预处理器的原因之一,并且是一个很好的理由,这样可以节省大量的时间和汗水。创建一个minxin来处理浏览器的前缀问题是一个很简单的,并且能节省大量的重复工作和痛苦的代码编辑,我们来看一个例子。
@mixin border-radius($values) { -webkit-border-radius: $values; -moz-border-radius: $values; border-radius: $values; } p { @include border-radius(10px); }
.border-radius(@values) { -webkit-border-radius: @values; -moz-border-radius: @values; border-radius: @values; } p { .border-radius(10px); }
border-radius(values) { -webkit-border-radius: values; -moz-border-radius: values; border-radius: values; } p { border-radius(10px); }
p { -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
使用text-shadow的多重属性制作3D文本效果是一个很好的方法。唯一麻烦的问题就是修改文本阴影的颜色。如果我们使用Mixin和颜色函数的话,实现3D文本效果就非常的轻松了,我们来尝试一下。
@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); }
.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); }
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中省略了花括号{}
和分号;
。
上面三种方法实现的效果都是一样的:
我第一次接触CSS预处理器的时候,我就想着使用数字或者变量进行运算。使用数值和变量运算,可以很方便的实现适应屏幕大小的布局处理。只需要定义宽度的变量,我们就可以很方便的根据需求实现布局。下面的例子就是这么做的。
$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; }
@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; }
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; }
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的注释方式),也支持//
单行注释方式(类似于Javascript的注释方式)。
需要注意,如果你要压缩文件,你需要把所有注释都删除。
三个预处理器我们都覆盖了(sass、less和stylus),都以他们独特的特性完成了相同的效果。这样让开发人员更好的选择适合自己的CSS预处理器,从而更好的维护自己的代码,提高开发效率。
虽然不是开发的要求,但CSS预处理器可以节省大量的时间,并且有一些非常有用的功能。
我鼓励大家尽可能的尝试使用CSS预处理器,这样就可以有效的让你选择一个你最喜欢的和知道他为什么是受人青睐的。如果你还没有尝试过使用CSS预处理器来写你的CSS样式,我强烈建议你尝试一下。
如果你有最喜欢的CSS预处理器的功能,我并没有提到的,希望在下面的评论中与我们分享。
译者手语: 整个翻译依照原文线路进行,并在翻译过程略加了个人对技术的理解。如果翻译有不对之处,还烦请同行朋友指点。谢谢!
更多CSS预处理器的对比 — Sass、Less和Stylus 相关文章请关注PHP中文网!