CSS预处理器Sass(Scss)、Less、Stylus
2016-03-09 19:56
561 查看
CSS 预处理编译器能让我成程序化其的方式编写CSS代码,可以引入CSS中没有的变量、条件、函数等特性,从而让代码更简单易维护,但一般按预处理器语法编写的代码无法直接在浏览器中运行,需用通过工具比如gulp转换成标准的CSS语法,从而在浏览器中运行。个人理解它是标准CSS语法的扩展及增强,能在一定程度上提高编码效率。三种预处理器的对比:
Sass诞生是最早也是最成熟的CSS预处理器,有Ruby社区和Compass支持;安装、编译依赖Ruby环境;Stylus早期服务器Node JS项目,在该社区得到一定支持者,安装、编译依赖NodeJs环境;LESS出现于2009年,支持者远超于Ruby和Node JS社区,安装、编译依赖NodeJs环境,代表bootstrap;Sass和LESS语法较为严谨、严密,而Stylus语法相对散漫(借鉴python),其中LESS学习起来更快一些,因为他更像CSS的标准;Sass和LESS相互影响较大,其中Sass受LESS影响,已经进化到了全面兼容CSS的SCSS;Sass和LESS都有第三方工具提供转译,特别是Sass和Compass是绝配;Sass、LESS和Stylus都具有变量、作用域、混合、嵌套、继承、运算符、颜色函数、导入和注释等基本特性,而且以“变量”、“混合”、“嵌套”、“继承”和“颜色函数”称为五大基本特性,各自特性实现功能基本相似,只是使用规则上有所不同;Sass和Stylus具有类似于语言处理的能力,比如说条件语句、循环语句等,而LESS需要通过When等关键词模拟这些功能,在这一方面略逊一层;最后摘录一下为什么要用CSS预处理器
比如这样的需求:“
尽管完全是一个规则里定义出的,但你只能这样写CSS:
比如这样:
页面重构时,需要频繁修改class name;
这个问题在后端人员掌握着视图层的时候格外突出,前后端耗费很多沟通成本。
要约束上下文的时候非常无力
比如“只有在
如果我们想要建立一种代码风格,只允许CSS Class代表UI模块的抽象——改动样式时不至于通知后端改模板——我们就要将上面这个例子的
——而这正是CSS的短板,CSS体系内的用法只有复制粘贴。
至于如何用预编译语言做mixin,一个非常好的SASS示例由 @nightire 在这个回答里给出,容我摘录一小段:
比如对rgba背景的兼容:
举个例子:原先我们只需要在chrome/firebug里面找到相应的选择器,如
曾经有一个观点是预编译可以解决样式覆写的问题,而我觉得,正是预编译语言模糊了样式覆写的问题,而导致要解决样式相互覆写的问题时,问题已经变得规模庞大而难以解决。
举个极端的例子:
因此,实际项目中衡量预编译方案时,还是得想想,比起带来的额外维护开销,预编译有没有解决更大的麻烦。
来源: <https://segmentfault.com/q/1010000002527156/a-1020000002527759>
来自为知笔记(Wiz)
Sass诞生是最早也是最成熟的CSS预处理器,有Ruby社区和Compass支持;安装、编译依赖Ruby环境;Stylus早期服务器Node JS项目,在该社区得到一定支持者,安装、编译依赖NodeJs环境;LESS出现于2009年,支持者远超于Ruby和Node JS社区,安装、编译依赖NodeJs环境,代表bootstrap;Sass和LESS语法较为严谨、严密,而Stylus语法相对散漫(借鉴python),其中LESS学习起来更快一些,因为他更像CSS的标准;Sass和LESS相互影响较大,其中Sass受LESS影响,已经进化到了全面兼容CSS的SCSS;Sass和LESS都有第三方工具提供转译,特别是Sass和Compass是绝配;Sass、LESS和Stylus都具有变量、作用域、混合、嵌套、继承、运算符、颜色函数、导入和注释等基本特性,而且以“变量”、“混合”、“嵌套”、“继承”和“颜色函数”称为五大基本特性,各自特性实现功能基本相似,只是使用规则上有所不同;Sass和Stylus具有类似于语言处理的能力,比如说条件语句、循环语句等,而LESS需要通过When等关键词模拟这些功能,在这一方面略逊一层;最后摘录一下为什么要用CSS预处理器
1# CSS无法递归式定义
CSS语法不支持递归定义的表达式,所以你没有办法用一个语句定义一个启发式的规则。比如这样的需求:“
.w后面跟着一个数字,这个数字代表着width为百分之多少”(bootstrap的栅格系统就包含12种相对父级宽度的类定义)。
尽管完全是一个规则里定义出的,但你只能这样写CSS:
.w1 { width: 1% } .w2 { width: 2% } /** .w3 ... ... .w99 **/.w100 { width: 100% }这样将造成很大的冗余,修改费时费力。但如果预编译CSS,就非常简单了:
@maxnumber : 100 ; .makeWidthRules(@number) when(@number <= @maxnumber ){ .w@{number}{ width: 1% * @number ; } .makeWidthRules(@number + 1) ; } .makeWidthRules(1) ;
2# CSS的mixin式复用性支持不够
使用纯CSS,我们可以抽象出一些常用的布局CSS属性组合,通过CSS的类组合来达成常见的mixin式复用。比如这样:
<style>.tc { text-align: center; }.m { margin-left: auto; margin-right: auto; }.w50p { width: 50%; }.db { display: block; }</style><div class="tc m w50p"><img class="db"></div>这种方案有几个问题:
页面重构时,需要频繁修改class name;
这个问题在后端人员掌握着视图层的时候格外突出,前后端耗费很多沟通成本。
要约束上下文的时候非常无力
比如“只有在
ul下面的
img.db允许是
display:block”的规则,写成
ul img.db { display: block; }就完全跑偏了——它违背了你创建这个
.db类时的本意,造成了代码的可读性和可维护性下降。如果你要改动规则,需要同时修改HTML和CSS,也可能造成新的样式问题。
如果我们想要建立一种代码风格,只允许CSS Class代表UI模块的抽象——改动样式时不至于通知后端改模板——我们就要将上面这个例子的
tc m w50p换用一个有实际语义的类名如
headwrap,然后在CSS内部实现mixin。
——而这正是CSS的短板,CSS体系内的用法只有复制粘贴。
至于如何用预编译语言做mixin,一个非常好的SASS示例由 @nightire 在这个回答里给出,容我摘录一小段:
.btn-standout { @extend .btn; @extend .btn-block; @media (max-width: $screen-xs-max) { @include button-size( $padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $border-radius-large ); } &.sell { @extend .btn-primary; } }
3# 预编译可缓解多浏览器兼容造成的冗余
进入CSS3的时代,旧式CSS hack如filter,新式兼容前缀如
-webkit-等,都是冗余,修改的时候也需要修改多处,不容易维护。
比如对rgba背景的兼容:
.bg { filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#ccff825b,endcolorstr=#ccff825b); }:root .bg { -ms-filter: none; background: rgba(255,130,91,0.8) }在LESS里面,写个函数就能解决,多次复用也不需要看到如此之多的hack:
.rgbaBG(@c , @a){ @rgba : rgba(red(@c),green(@c),blue(@c),@a); @shim : argb(@rgba) ; filter: ~"progid:DXImageTransform.Microsoft.gradient(startcolorstr=@{shim},endcolorstr=@{shim})" ; :root & { -ms-filter: none ; background: @rgba ; } } .bg { .rgbaBG(#ff825b, 0.8) ; }此外,使用LESS时,可以很方便地使用base64 data uri的方案。不需要直接面临在CSS中一大坨字符:
.bg { background: data-uri('../data/image.jpg'); }SASS的类似方案见评论。
N# 预编译不是万金油
预编译不是万金油,CSS的好处在于简便、随时随地被使用和调试。预编译CSS步骤的加入,让我们开发工作流中多了一个环节,调试也变得更麻烦了。举个例子:原先我们只需要在chrome/firebug里面找到相应的选择器,如
.popup .popup-wrap .head,源文件里面ctrl+F查找
.popup .popup-wrap .head就可以快速定位语句。现在我们无法直接在预编译文件中查找,而需要寻找上下文,因为它在LESS中通常是这样被定义的:
.popup { .popup-wrap { .head { } } }更大的问题在于,预编译很容易造成后代选择器的滥用。
曾经有一个观点是预编译可以解决样式覆写的问题,而我觉得,正是预编译语言模糊了样式覆写的问题,而导致要解决样式相互覆写的问题时,问题已经变得规模庞大而难以解决。
举个极端的例子:
.popup { font-size: 12px; a { font-size: 13px; } .head { font-size: 18px; } } .informative { font-size: 14px; .head { font-size: 16px; } }如果我有这么一个文档结构
.popup.informative > .head > a,需要
a的
font-size为
17px,你能快速想明白怎么改吗?叠罗汉式地再叠一层?还是再糊一层墙皮,加一行样式?还是干脆用
!important轰炸一番?
因此,实际项目中衡量预编译方案时,还是得想想,比起带来的额外维护开销,预编译有没有解决更大的麻烦。
来源: <https://segmentfault.com/q/1010000002527156/a-1020000002527759>
来自为知笔记(Wiz)
相关文章推荐
- css限制显示字数,文字长度超出部分用省略号表示
- TextView设置不同样式
- CSS权威指南 笔记
- css3 怎么实现像书籍装订线的效果
- css清除浮动
- 使用 CSS 去掉 iPhone 网页上按钮的超大圆角默认样式
- CSS3响应式布局
- CSS归纳总结
- rails torial 中css/js引用的版本坑
- [css] 清除浮动的方式总结
- CSS设置小技巧
- css设置文字自动折行,遇到整个单词时截断,并用中划线-连接
- CSS3技巧:利用css3径向渐变做一张优惠券(转)
- CSS系列:长度单位&字体大小的关系em rem px
- CSS 布局
- CSS - 针对不同浏览器的写法
- css3实现背景切换
- css3技巧——产品列表之鼠标滑过效果(一)
- 探索css sprite
- 利用css写出二级导航