代码改变世界

(转载)SmashingMagazine] LESS介绍,和与Sass的比较

2012-07-10 00:11  破狼  阅读(3587)  评论(0编辑  收藏  举报

    本文来自thoughtworks Jing Ren ,感谢Jing Ren的翻译(中文版英文原文)。本人觉得很惭愧,有点窃取的行为,所以我必须再次声明来自我们可爱的Jing Ren,并再次感谢她的不辞辛苦。

    如果你还在为web前段css设计,维护,开发困扰的,我觉得你可以尝试下LESS或者Sass另类的动态css体系。

原文如下:

      自从我几个月前开始使用LESS,我就成文了它的忠实粉丝。CSS对我来说从来都不是问题,但是LESS可以把一个主题中的颜色都设置成变量,来保持我的网 站在风格上统一,这个想法让我很着迷。就好像我们有一个调色板,上面有固定的几个颜色,我们可以从中选择,而不至于被颜色搞的发疯,也不至于偏离轨道。

less-sass1.jpg

LESS和Sass,还可以做更多事情。它们有很多共同点,比如说:

混合(Mixins)- Classes for classes

带参数的混合(Parametric mixins) - Classes to which you can pass parameters, like functions.

嵌套的规则 (Nested Rules)- class嵌套class,以减少重复代码

运算(Operations)- CSS中的计算

颜色方法(Color functions) - 用来修改颜色

命名空间(Namespaces)- 为样式分组,并且可以通过组名进行访问

作用域(Scope)- 对样式进行暂时的修改

JavaScript求值(JavaScript evaluation) - 在CSS里执行JavaScript表达式

LESS和Sass最大的区别是他们处理的方式。LESS是一个JavaScript库,所以,它在客户端执行。

而,Sass, 需要Ruby,在服务器端运行。许多开发人员不选择LESS因为在浏览器里Javascript解析less代码返回CSS代码需要额外的时间。有几个方 法可以避免这个问题。一个是只在开发阶段使用LESS。一旦开发完成,我把LESS转化成CSS代码,放在另外一个文件里,在引用less文件的地方引用 这个css文件。另一个方法是使用LESS.app来编译和最小化你的LESS文件。这两种方法,都可以减少对style的影响,并且可以避免浏览器不能运行JavaScript带来的问题。虽然可能性很小,但总是有可能的。

更 新:上面的论述引起了热烈的讨论,甚至在Twitter上也有相关的争论。请大家同时也考虑Adam Stacoviak的回复“现实是Sass需要Ruby,但是,它并不一定要在Server端转化成CSS。它可以本地编译(就像LESS声称的一样), 并且编译过的CSS也可以和之前的CSS一样使用。因为这里是Smashing Magazine,读者一定非常多,我猜这里有很大一部分读者正在使用Mac来读这篇文章。那么,所有的Mac电脑都默认支持Ruby,所以安装、运行 Sass只需要一个命令行 (sudo gem install sass)”。

一旦你安装了Sass,你就可以在本地把Sass编译成CSS,并且在你的项目里引用这个CSS。如果你不知道如何开始使用Sass(或者Compass),那么你可以读读这篇文章:“Getting Started with Sass and Compass”。感谢Adam指出问题。

Less Is More

安装

在你的项目使用LESS非常的容易:

1. 复制less.js

2. 创建一个样式表,比如叫style.less

3. 添加下面代码到HTML的<head>块里

<link rel="stylesheet/less" type="text/css" href="http://anotherwayaround.blog.163.com/blog/styles.less">
<script src="http://anotherwayaround.blog.163.com/blog/less.js" type="text/javascript"></script>

注 意link标签的ref属性。你需要以“/less”结尾,才能工作。紧跟在link标签的后面,要包含这个script标签。如果你使用的是HTML5 的语法,那么你可以去掉 type="text/css" 和 type="text/javascript" 这两句。

还有一个服务器端的LESS。在服务器端使用LESS最简单的办法是使用Node Package Manager (NPM)

变量(Variables)

如 果你是一个developer,变量是你最好的朋友。当你需要多次使用同一个信息的时候(比如字体,颜色),把它设置成一个变量就是情理之中的事儿了。通 过这种方法,保证了一致性,并且不用翻遍文件来找一个十六进制的数字复制粘贴了。甚至你还可以对这个十六进制数进行加减运算。比如说:

@blue: #00c;
@light_blue: @blue + #333;
@dark_blue: @blue - #333;

如果我们把这3个颜色应用到三个div上,我们就可以看到一个颜色渐进的效果:

1.png

应用的顺序是:@light_blue 、@blue、@dark_blue

LESS和Sass定义变量唯一的不同就是Less使用@,Sass使用$。 还有一些作用域的不同,后面我会简要介绍一下。

混合(Mixins)

有时候,我们希望创建一些样式,可以在整个样式表里重复使用。你可以再HTML里给这些元素添加相同的class,而使用LESS,只修改CSS也可以完成这样的功能。举个例子,在页面上有两个元素要使用一个相同的style:

.border {
border-top: 1px dotted #333;
}

article.post {
background: #eee;
.border;
}

ul.menu {
background: #ccc;
.border;
}

上面的代码,实现了和在HTML里给这两个元素都加上class ".bordered"类似的功能,而这样做,你就不需要修改HTML了。效果也很好:

2.png

两个元素都有了border-top的样式

而在Sass里,你需要先使用@mixin定义一个样式。之后,使用@include来调用它:

@mixin border {
border-top: 1px dotted #333;
}

article.post {
background: #eee;
@include border;
}

ul.menu {
background: #ccc;
@include border;
}

带参数的混合(Parametric Mixins)

就好像在CSS中使用function,会对优化那些看起来重复冗长的CSS很有帮助。一个最有用的例子就是,我们在使用CSS3的过程中,有些样式需要使用不同的前缀才能支持不同的浏览器。Nettuts+上有一篇非常好的文章,Jeffrey Way写的,wonderful webcast and article,里面介绍了很多解决常用的CSS3属性前缀问题的mixins方法。举个例子,对于最简单的圆角:

.border-radius( @radius: 3px ) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}

在这种情况下,.border-radius这个class就默认有3px的圆角,你还可以在调用时传入其他的值,如果使用.border-radius(10px),那么圆角就是10px。

在Sass里的语法和在LESS里类似,只是要使用$来定义变量,并且先使用@mixin定义一个样式。再使用@include来调用它。

选择器继承(Selector Inheritance)

这是一个LESS没有的功能。使用这个功能,你可以使用@extend方法把一个selector的样式添加到另一个selector里。

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

.footer {
     @extend .menu;
}

/* will render like so: */
.menu, .footer {
     border: 1px solid #ddd;
}

嵌套的规则(Nested Rules)

在CSS里嵌套的class和id是解决样式之间互相影响的唯一办法。但是这样写很麻烦。比如使用一个这样的selector

#site-body .post .post-header h2

是很不爽的,而且浪费空间。使用LESS,你就可以更高效的嵌套id,class和元素。比如上面的例子,你就可以写成这样:

#site-body { …

    .post { …

        .post-header { …

            h2 { … }

            a { …

                 &:visited { … }
                 &:hover { … }
            }
        }
    }
}

这段代码和上面那段丑陋的CSS代码功能是相同的,但是更易读,并且占用空间更少。并且,你还可以使用&符号来引用当前所在的元素,就像JavaScript里的this一样。

运算(Operations)

你可能期望有这样的功能:在你的样式表中可以对常数或者变量进行计算。

@base_margin: 10px;
@double_margin: @base_margin * 2;

@full_page: 960px;
@half_page: @full_page / 2;
@quarter_page: (@full_page / 2) / 2;

对于@quarter_page这个变量,我知道我可以直接除以4,但是我希望借这个机会阐述一下括号的用法,括号用来调整执行顺序的规则在这里也适用。如果样式包含多个属性,那括号也是必须的,例如:border: (@width / 2) solid #000。

Sass 在计算数字方面比LESS更加强大。它在内部自带一个各种单位的转换表。Sass可以对未知的度量单位进行计算,并且打印出结果。This feature was apparently introduced in an attempt to future-proof the library against changes made by the W3C.

/* Sass */
2in + 3cm + 2pc = 3.514in

/* LESS */
2in + 3cm + 2pc = Error

颜色方法(Color Functions)

前 面我们提到LESS帮助我计算出一个颜色的组合。这个功能是颜色方法的一部分。假设,在你的样式中,使用一个标准的蓝色,你希望在一个“提交”按钮上使用 这个颜色,并做成渐变效果。你可以打开Photoshop或者其他什么图片编辑器,来得到这个蓝色渐变需要的更深或者更浅的蓝色,你也可以直接使用 LESS提供的颜色方法:

@blue: #369;

.submit {
    padding: 5px 10px;
    border: 1px solid @blue;
    background: -moz-linear-gradient(top, lighten(@blue, 10%), @blue 100%); /*Moz*/
    background: -webkit-gradient(linear, center top, center bottom, from(lighten(@blue, 10%)), color-stop(100%, @blue)); /*Webkit*/
    background: -o-linear-gradient(top, lighten(@blue, 10%) 0%, @blue 100%); /*Opera*/
    background: -ms-linear-gradient(top, lighten(@blue, 10%) 0%, @blue 100%); /*IE 10+*/
    background: linear-gradient(top, lighten(@blue, 10%) 0%, @blue 100%); /*W3C*/
    color: #fff;
    text-shadow: 0 -1px 1px rgba(0,0,0,0.4);
}

这 个lighten方法可以先行的使某个颜色变量多少百分比。在上面的代码里,它会使标准蓝色变亮10%。这个方法让我们可以方便的改变渐变元素的颜色,也 可以方便的改变基准颜色。这为我们支持多主题提供的巨大的帮助。另外,如果你使用带参数的方法,就像上面的例子那样,你可以把浏览器前缀封装在一个方法 里,这样你就可以简单的写成这样:

.linear-gradient(lighten(@blue), @blue, 100%);

你可以得到这样的效果:

Image.png

还有很多其他的方法,改变颜色的深度,饱和度,甚至转变成另外一个颜色。我建议大家自己试试,看能做出什么效果。

Sass似乎提供了更多的颜色选项——但我并不经常用到他们。变深和变浅是我最常用到的方法。更多的细节,可以参考这篇文章:in-depth article on the topic

条件语句和控制(Conditionals and Control)

这个功能非常棒,但是LESS并不支持。使用Sass,你可以使用if {} else {} 语句,并且可以使用for{}循环。它还支持and,or和not关键字,还支持<, >, <=, >=和==等运算符。

/* Sample Sass "if" statement */
@if lightness($color) > 30% {
  background-color: #000;
} @else {
  background-color: #fff;
}

/* Sample Sass "for" loop */
@for $i from 1px to 10px {
  .border-#{i} {
    border: $i solid blue;
  }
}

命名空间(Namespaces)

我们可以使用命名空间组织样式的层次结构,LESS允许我们创建一组经常被使用的样式,并且可以在其他地方调用它们。比如,我们创建了一组样式,叫defaults,当某些元素需要使用这些样式的时候,就可以从这个组里面取。

#defaults {
     .nav_list () {
          list-style: none;
          margin: 0; padding: 0;
     }
     .button () { … }
     .quote () { … }
}

在后面的代码里,如果有个nav元素里的ul需要使用某个默认样式,我们简单的调用它就可以了:

nav ul {
     #defaults > .nav_list;
}

作用域(Scope)

作用域在编程过程中非常重要,同样在LESS中也很重要。如果你在根级别定义了一个变量,那么你可以在文档的任何一个地方调用它。如果你在一个selector里定义了一个同名的变量,那么它会覆盖上级的变量,并且只有在这个selector里才能取到这个值。

@color: #00c; /* blue */

#header {
     @color: #c00; /* red */

     border: 1px solid @color; /* will have a red border */
}

#footer {
     border: 1px solid @color; /* will have a blue border */
}

因为我们在#header里重新定义了这个变量,所以在这个变量在这个selector里的取值和外面不一样。在这个selector之前和之后的调用,都会保留外面的值。

LESS对作用域的处理和Sass有一点不同。对于上面的代码,一旦@color变成red,那么后面的所有代码都会被解释成red。

注释(Comments)

这部分非常基础,LESS支持两种注释类型。标准的CSS注释,/* comment */,它可以通过LESS的处理并且被输出。单行的注释:// comment,但是并不会被输出,所以,这种注释是“无声的”。

导入(Importing)

导 入也是一个必须的功能。标准的@import: 'classes.less'在LESS下可以工作。如果你导入的也是一个LESS文件,那么后缀名可以省略不写,所以可以写成@import 'classes'。如果你要引入的文件不需要LESS进行处理,那么就需要写上后缀名,比如.css(例如:@import: 'reset.css')。

字符串插入(String Interpolation)

样式里可以插入字符串变量:

@base_url = 'http://coding.smashingmagazine.com';/
background-image: url("@{base_url}/images/background.png");

转义(Escaping)

如果你要使用一个不合法的CSS语法,或者LESS不能识别的语法,这个转义功能就很重要了。通常,使用这个功能是做一个疯狂的Microsoft Hack。为了避免LESS抛异常,你需要对它们进行转义:

.class {
     filter: ~"progid:DXImageTransform.Microsoft.Alpha(opacity=20)";
}

/* Will actually be outputted like this: */
.class {
     filter: progid:DXImageTransform.Microsoft.Alpha(opacity=20);
}

Javascript求值(JavaScript Evaluation)

这是我最喜欢的LESS的功能:在样式表里使用Javascript功能——太好了。你可以使用表达式,并且可以引用环境变量,Javascript代码需要在`符号中间:

@string: `'howdy'.toUpperCase()`; /* @string becomes 'HOWDY' */

/* You can also use the previously mentioned interpolation: */
@string: 'howdy';
@var: ~`'@{string}'.topUpperCase()`; /* becomes 'HOWDY' */

/* Here we access part of the document */
@height = `document.body.clientHeight`;

输出格式(Output Formatting)

LESS没有提供输出设置,Sass提供4中输出格式:嵌入式的、紧凑的、压缩的、展开的。

写在最后

这 两个框架有很多共同点。对于那些写代码的实际设计师来说,他们都是强大的工具,来帮助开发人员更高效更快速的工作。如果你是一个Ruby或者HAML的粉 丝,那么Sass可能用起来更顺手。对我这样一个Javascript和PHP的geek来说,我更喜欢LESS,因为它可以方便的包含和执行 Javascript表达式。我不是很确定在我真的理解了如何在我的样式表里使用它们是最好的,但是我正在尝试。如果你曾经用过它们中的某一个或者两个, 我希望能听到你们的反馈。欢迎大家来交流使用方法,技巧,或者对我这篇文章的纠错。

额外的参考文献:

less官方:http://www.lesscss.net/

飞长(王玉林)(less中文发起人):http://www.veryued.org/

最后再次声明本文翻译来自:

https://my.thoughtworks.com/groups/china-ux-community/blog/2012/06/24/%E7%BF%BB%E8%AF%91smashingmagazine-less%E4%BB%8B%E7%BB%8D-%E5%92%8C%E4%B8%8Esass%E7%9A%84%E6%AF%94%E8%BE%83