初步认识Less

LESS 是一个流行的样式表语言,它提供了 CSS3 也不曾实现的多种功能,让您编写 CSS 更加方便,更加直观。LESS 已经被普遍使用在多种框架中 ( 例如:BootStrap)。本文将介绍 LESS 产生的背景、优点、演化与 CSS 之间的转化,及其典型的应用场景,并将其与其余样式表语言进行比较。相信前端开发工程师会喜欢 LESS,灵活运用 LESS 以提升开发效率。javascript

 

LESS 背景介绍

LESS 提供了多种方式能平滑的将写好的代码转化成标准 CSS 代码,在不少流行的框架和工具盒中已经能常常看到 LESS 的身影了(例如 Twitter 提供的 bootstrap 库就使用了 LESS)。那么,LESS 是从何而来呢?它和 SASS 等样式表语言又有何区别呢?css

 
图 1.LESS 的官网介绍

图 1.LESS 的官网介绍

根 据维基百科上的介绍,其实 LESS 是 Alexis Sellier 受 SASS 的影响建立的开源项目。当时 SASS 采用了缩进做为分隔符来区分代码块,而不是 CSS 中广为使用的括号。为了让 CSS 现有用户使用起来更为方便,Alexis 开发了 LESS 并提供了相似的功能。在一开始,LESS 的解释器也一样是由 Ruby 编写,后来才转而采用了 JavaScript. LESS 代码既能够运行在客户端,也能够运行在服务器端。在客户端只要把 LESS 代码和相应的 JavaScript 解释器在同一页面引用便可;而在服务器端,LESS 能够运行在 Node.js 上,也能够运行在 Rhino 这样的 JavaScript 引擎上。html

 

说一点题外话,其实如今的 SASS 已经有了两套语法规则:一个依旧是用缩进做为分隔符来区分代码块的;另外一套规则和 CSS 同样采用了大括弧做为风格符。后一种语法规则又名 SCSS,在 SASS 3 以后的版本都支持这种语法规则。SCSS 和 LESS 已经愈来愈像了,它俩之间更详细的对比能够参考 此连接前端

 

LESS 高级特性

我 们知道 LESS 拥有四大特性:变量、混入、嵌套、函数。这些特性在其余文章中已经有所介绍,这里就不复述了。其实,LESS 还拥有一些颇有趣的特性有助于咱们的开发,例如模式匹配、条件表达式、命名空间和做用域,以及 JavaScript 赋值等等。让咱们来逐一看看这些特性吧。java

 

模式匹配:

相信你们对 LESS 四大特性中的混入 (mixin) 依然印象深入吧,您用它可以定义一堆属性,而后轻松的在多个样式集中重用。甚至在定义混入时加入参数使得这些属性根据调用的参数不一样而生成不一样的属性。那 么,让咱们更进一步,来了解一下 LESS 对混入的更高级支持:模式匹配和条件表达式。node

首先,让咱们来回顾一下普通的带参数的混入方式:git

 
清单 1. 带参数(及参数缺省值)的混入
Html代码  
.border-radius (@radius: 3px) {   
 border-radius: @radius;   
 -moz-border-radius: @radius;   
 -webkit-border-radius: @radius;   
}   
.button {   
 .border-radius(6px);   
}   
.button2 {   
 .border-radius();   
} 

 

清单 2. 混入生成的 CSS 代码
Html代码  
.button {   
 border-radius: 6px;   
 -moz-border-radius: 6px;   
 -webkit-border-radius: 6px;   
}   
.button2 {   
 border-radius: 3px;   
 -moz-border-radius: 3px;   
 -webkit-border-radius: 3px;   
}  

  从上面这个例子能够看出,在混入咱们能够定义参数,同时也能够为这个参数指定一个缺省值。这样咱们在调用这个混入时若是指定了参数 .border-radius(6px),LESS 就会用 6px来替换,若是不指定参数来调用 .border-radius(),LESS 就会用缺省的 3px来替换。如今,咱们更近一步,不只仅经过参数值来更改最终结果,而是经过传入不一样的参数个数来匹配不一样的混入。github

 
清单 3. 利用不一样的参数个数来匹配不一样的混入

Html代码  web

.mixin (@a) {   
 color: @a;   
 width: 10px;   
}   
.mixin (@a, @b) {   
 color: fade(@a, @b);   
}   
  
.header{   
   .mixin(red);   
}   
.footer{   
   .mixin(blue, 50%);   
}  

 

清单 4. 不一样参数个数调用后生成的 CSS 代码
Html代码   
.header {   
 color: #ff0000;   
 width: 10px;   
}   
.footer {   
 color: rgba(0, 0, 255, 0.5);   
}  

 这个例子有些像 Java 语言中的方法调用有些相似,LESS 能够根据调用参数的个数来选择正确的混入来带入。如今,咱们了解到经过传入参数的值,以及传入不一样的参数个数可以选择不一样的混入及改变它的最终代码。这两 个例子的模式匹配都是很是容易理解的,让咱们换个思路,上面的例子中参数都是由变量构成的,其实在 LESS 中定义参数是能够用常量的!模式匹配时匹配的方式也会发生相应的变化,让咱们看个实例。npm

 
清单 5. 用常量参数来控制混入的模式匹配

 Html代码  

.mixin (dark, @color) {   
 color: darken(@color, 10%);   
}   
.mixin (light, @color) {   
 color: lighten(@color, 10%);   
}   
.mixin (@zzz, @color) {   
 display: block;   
 weight: @zzz;   
}   
  
.header{   
   .mixin(dark, red);   
}   
.footer{   
   .mixin(light, blue);   
}   
.body{   
   .mixin(none, blue);   
}

 

 清单 6. 常量参数生成的 CSS 代码

 Html代码  

.header {   
 color: #cc0000;   
 display: block;   
 weight: dark;   
}   
.footer {   
 color: #3333ff;   
 display: block;   
 weight: light;   
}   
.body {   
 display: block;   
 weight: none;   
}  

 经过这个例子咱们能够看出,当咱们定义的是变量参数时,由于 LESS 中对变量并无类型的概念,因此它只会根据参数的个数来选择相应的混入来替换。而定义常量参数就不一样了,这时候不只参数的个数要对应的上,并且常量参数的 值和调用时的值也要同样才会匹配的上。值得注意的是咱们在 body 中的调用,它调用时指定的第一个参数 none 并不能匹配上前两个混入,而第三个混入 .mixin (@zzz, @color)就不一样了,因为它的两个参数都是变量,因此它接受任何值,所以它对三个调用都能匹配成功,所以咱们在最终的 CSS 代码中看到每次调用的结果中都包含了第三个混入的属性。

 

最后,咱们把清单 1 中的代码作略微改动,增长一个无参的混入和一个常量参数的混入,您猜猜看最终的匹配结果会发生什么变化么?

 
清单 7. 无参和常量参数的模式匹配

 Html代码  

.border-radius (@radius: 3px) {   
 border-radius: @radius;   
 -moz-border-radius: @radius;   
 -webkit-border-radius: @radius;   
}   
  
.border-radius (7px) {   
 border-radius: 7px;   
 -moz-border-radius: 7px;   
}   
.border-radius () {   
 border-radius: 4px;   
 -moz-border-radius: 4px;   
 -webkit-border-radius: 4px;   
}   
  
.button {   
 .border-radius(6px);   
}   
.button2 {   
 .border-radius(7px);   
}   
.button3{   
.border-radius();        
}

 下面的结果可能会出乎您的意料,无参的混入是可以匹配任何调用,而常量参数很是严格,必须保证参数的值 (7px)和调用的值 (7px)一致才会匹配。

 
清单 8. 加入了无参混入后生成的 CSS 代码

 Html代码    

.button {   
 border-radius: 6px;   
 -moz-border-radius: 6px;   
 -webkit-border-radius: 6px;   
 border-radius: 4px;   
 -moz-border-radius: 4px;   
 -webkit-border-radius: 4px;   
}   
.button2 {   
 border-radius: 7px;   
 -moz-border-radius: 7px;   
 -webkit-border-radius: 7px;   
 border-radius: 7px;   
 -moz-border-radius: 7px;   
 border-radius: 4px;   
 -moz-border-radius: 4px;   
 -webkit-border-radius: 4px;   
}   
.button3 {   
 border-radius: 3px;   
 -moz-border-radius: 3px;   
 -webkit-border-radius: 3px;   
 border-radius: 4px;   
 -moz-border-radius: 4px;   
 -webkit-border-radius: 4px;   
}

 

条件表达式

有了模式匹配以后是方便了不少,咱们能根据不一样的需求来匹配不一样的混入,但更进一步的就是利用条件表达式来更加准确,更加严格的来限制混入的匹配,实现的方式就是利用了 when这个关键词。

 清单 9. 利用条件表达式来控制模式匹配

 Html代码  

.mixin (@a) when (@a >= 10) {   
 black;   
}   
.mixin (@a) when (@a < 10) {   
 white;   
}   
.class1 { .mixin(12) }   
.class2 { .mixin(6) }  

 

 清单 10. 条件表达式生成的 CSS 代码

 Html代码  

.class1 {   
 black;   
}   
.class2 {   
 white;   
} 

 利用 When 以及 <, >, =, <=, >= 是十分简单和方便的。LESS 并无停留在这里,并且提供了不少类型检查函数来辅助条件表达式,例如 iscolorisnumberisstringiskeywordisurl等等。

 
清单 11. 条件表达式中支持的类型检查函数

 Html代码  

.mixin (@a) when (iscolor(@a)) {   
 black;   
}   
.mixin (@a) when (isnumber(@a)) {   
 white;   
}   
.class1 { .mixin(red) }   
.class2 { .mixin(6) }  

 

清单 12. 类型检查匹配后生成的 CSS 代码

Html代码  

.class1 {   
 black;   
}   
.class2 {   
 white;   
}  

 另外,LESS 的条件表达式一样支持 AND 和 OR 以及 NOT 来组合条件表达式,这样能够组织成更为强大的条件表达式。须要特别指出的一点是,OR 在 LESS 中并非用 or 关键字,而是用 , 来表示 or 的逻辑关系。

 
清单 13. AND,OR,NOT 条件表达式

 Html代码    

.smaller (@a, @b) when (@a > @b) {   
   black;   
}   
.math (@a) when (@a > 10) and (@a < 20) {   
   red;   
}   
.math (@a) when (@a < 10),(@a > 20) {   
   blue;   
}   
.math (@a) when not (@a = 10)  {   
   yellow;   
}   
.math (@a) when (@a = 10)  {   
   green;   
}   
  
.testSmall {.smaller(30, 10) }   
.testMath1 {.math(15)}   
.testMath2 {.math(7)}   
.testMath3 {.math(10)}

 

清单 14. AND,OR,NOT 条件表达式生成的 CSS 代码

 Html代码   

.testSmall {   
 black;   
}   
.testMath1 {   
 red;   
 yellow;   
}   
.testMath2 {   
 blue;   
 yellow;   
}   
.testMath3 {   
 green;   
} 

 

 命名空间和做用域

LESS 所带来的变量,混入这些特性其实很大程度上避免了传统 CSS 中的大量代码重复。变量可以避免一个属性屡次重复,混入可以避免属性集的重复。并且使用起来更加灵活,维护起来也方便了许多,只要修改一处定义而无需修改 多处引用的地方。如今,让咱们更进一步,当我定义好了变量和混入以后,怎么能更好的控制和运用它们呢,怎么避免和其余地方定义的变量及混入冲突?一个显而 易见的想法就是像其余语言同样引入命名空间和做用域了。首先咱们来看一个 LESS 的做用域的例子。

 清单 15. 变量的做用域

 Html代码  

@var: red;   
#page {   
 @var: white;   
 #header {   
   color: @var;   
 }   
}   
#footer {   
 color: @var;   
}  

 在这个例子里,能够看到 header 中的 @var会首先在当前做用域寻找,而后再逐层往父做用域中寻找,一直到顶层的全局做用域中为止。因此 header 的 @var在父做用域中找到以后就中止了寻找,最终的值为 white。而 footer 中的 @var在当前做用域没找到定义以后就寻找到了全局做用域,最终的结果就是全局做用域中的定义值 red。

 
清单 16. 变量做用域例子生成的 CSS 代码

 Html代码   

#page #header {   
 color: #ffffff;  // white   
}   
#footer {   
 color: #ff0000;  // red   
} 

 了解了做用域以后让咱们再来看一下命名空间,咱们能够用命名空间把变量和混入封装起来,避免和其余地方的定义冲突,引用起来也十分方便,只要在前面加上相应的命名空间就能够了。

 
清单 17. 命名空间的例子
Html代码    
 @var-color: white;   
 #bundle {   
  @var-color: black;   
  
  .button () {   
    display: block;   
    border: 1px solid black;   
    @var-color;   
  }   
  .tab() { color: red }   
  .citation() { color: black}   
  .oops {weight: 10px}   
 }   
  
 #header {   
    color: @var-color;   
    #bundle > .button;   
    #bundle > .oops;  
}

 这里能够看出,咱们利用嵌套规则在 #bundle中创建了一个命名空间,在里面封装的变量以及属性集合都不会暴露到外部空间中,例如 .tab(), .citation()都没有暴露在最终的 CSS 代码中。而值得注意的一点是 .oops 却被暴露在了最终的 CSS 代码中,这种结果可能并非咱们想要的。其实一样的例子咱们能够在混入的例子中也能够发现,即无参的混入 .tab()是和普通的属性集 .oops不一样的。无参的混入是不会暴露在最终的 CSS 代码中,而普通的属性集则会如今出来。咱们在定义命名空间和混入时要当心处理这样的差异,避免带来潜在的问题。

 
清单 18. 命名空间例子生成的 CSS 代码
Html代码  
#bundle .oops {   
 weight: 10px;   
}   
#header {   
 color: #ffffff;   
 display: block;   
 border: 1px solid black;   
 #000000;   
 weight: 10px;   
}  

 

 JavaScript 赋值 (JavaScript Evaluation)

如 果能在 CSS 中使用一些 JavaScript 方法无疑是十分使人兴奋的,而 LESS 真正逐步加入这项功能,目前已经能使用字符串及数字的经常使用函数了,想要在 LESS 中运用 JavaScript 赋值只须要用反引号(`)来包含所要进行的操做便可。让咱们看看实例吧。

 
清单 19. JavaScript 赋值的例子
Html代码    
.eval {   
    js: `1 + 1`;   
    js: `(1 + 1 == 2 ? true : false)`;   
    js: `"hello".toUpperCase() + '!'`;   
    title: `process.title`;   
 }   
 .scope {   
    @foo: 42;   
    var: `this.foo.toJS()`;   
 }   
 .escape-interpol {   
    @world: "world";   
    width: ~`"hello" + " " + @{world}`;   
 }   
 .arrays {   
    @ary:  1, 2, 3;   
    @ary2: 1  2  3;   
    ary: `@{ary}.join(', ')`;   
    ary: `@{ary2}.join(', ')`;   
 }

 咱们能够看到,在 eval 中咱们能够用 JavaScript 作数字运算,布尔表达式;对字符串作大小写转化,串联字符串等操做。甚至最后可以获取到 JavaScript 的运行环境(process.title)。一样能够看到 LESS 的做用域和变量也一样在 JavaScript 赋值中使用。而最后的例子中,咱们看到 JavaScript 赋值一样运用于数组操做当中。其实 LESS 的 JavaScript 赋值还有支持其余一些方式,不过目前还没有公布出来。

 
清单 20. JavaScript 赋值生成的 CSS 代码
Html代码  
.eval {   
 js: 2;   
 js: true;   
 js: "HELLO!";   
 title: "/Users/Admin/Downloads/LESS/Less.app/Contents/Resources/engines/bin/node";   
}   
.scope {   
 var: 42;   
}   
.escape-interpol {   
 width: hello world;   
}   
.arrays {   
 ary: "1, 2, 3";   
 ary: "1, 2, 3";   
}  

 

LESS 开发的实用工具 – LESS.app

在 LESS 开发中,咱们能够用 LESS 提供的 JavaScript 脚原本在运行时解析,将 LESS 文件实时翻译成对应的 CSS 语法。以下面这个例子:

 清单 21. helloworld.html
Html代码  
<link rel="stylesheet/less" type="text/css" href="helloworld.less">   
<script src="less.js" type="text/javascript"></script>   
  
<div class="helloworld">Hello World!</div>  

 从上 面的示例能够看出,在 helloworld.less 引入以后咱们还添加了一个 JavaScript 文件,这个文件就是 LESS 的解释器,能够在 LESS 的官方网站上下载此文件。须要注意的是,要注意 LESS 文件和 LESS 解释器的引入顺序,确保全部的 LESS 文件都在 LESS 解释器以前。

 

看到这里也许有人会说,实时解析的话方便却是方便,能够性能上不就有损耗了么?比起普通 CSS 来讲多了一道解释的手续。也许还有的人对写好的 LESS 文件不太放心,但愿能看到解析以后的 CSS 文件来检查下是不是本身但愿的内容。这两个问题其实都是可以解决的,LESS 提供了服务端的方案,使用 npm 安装 LESS 以后就可以将您全部的 LESS 文件批量转化成 CSS 文件,而后您拿到 CSS 文件就能够为所欲为了,检查生成的内容是否有误,也能够直接在 HTML 中引用,不再用添加 LESS 的 JavaScript 文件来解析它了。关于这部分的详细安装信息,能够直接参考 LESS 官网上的介绍,这里就不复述了。

 

不过,对于 Mac 用户来讲还有一个更方便的工具可使用,它就是 less.app. 这是一个第三方提供的工具,使用起来十分方便,咱们能够在下图所示的界面上添加 LESS 文件所在的目录,此工具就会在右侧列出目录中包含的全部 LESS 文件。最酷的是,今后您就不用再操心惦记着要把 LESS 文件编译成 CSS 文件了,这个工具会在您每次修改完保存 LESS 文件时本身执行编译,自动生成 CSS 文件。这样,您就能够随时查看 LESS 代码的最终效果,检查目标 CSS 是否符合您的须要了,实在是太方便了!

 
图 2. 导入 LESS 文件夹的界面,左侧可添加存放在多个不一样路径的文件夹。

图 2. 导入 LESS 文件夹的界面,左侧可添加存放在多个不一样路径的文件夹。

 
图 3. 编译结果界面,在此可手动批量编译全部 LESS 文件。

图 3. 编译结果界面,在此可手动批量编译全部 LESS 文件。

更值为称道的是,LESS.app 仍是个免费软件,接受捐赠:)

 

总结

经过上面的简单介绍,但愿你们了解到了 LESS 的主要功能,相信 LESS 会让前端攻城师的工做更为轻松,更加灵活。更多的细节能够参考 LESS 官方网站。

 

 

 

原文:http://www.ibm.com/developerworks/cn/web/1207_shenyi_lesscss/

相关文章
相关标签/搜索