less的LESS 原理及使用方式

html-css020

less的LESS 原理及使用方式,第1张

本质上,LESS 包含一套自定义的语法及一个解析器,用户根据这些语法定义自己的样式规则,这些规则最终会通过解析器,编译生成对应的 CSS 文件。LESS 并没有裁剪 CSS 原有的特性,更不是用来取代 CSS 的,而是在现有 CSS 语法的基础上,为 CSS 加入程序式语言的特性。 我们可以直接在客户端使用 .less(LESS 源文件),只需要从http://lesscss.org下载 less.js 文件,然后在我们需要引入 LESS 源文件的 HTML 中加入如下代码:

<link rel=stylesheet/less type=text/css href=styles.less>

LESS 源文件的引入方式与标准 CSS 文件引入方式一样:

<link rel=stylesheet/less type=text/css href=styles.less>

需要注意的是:在引入 .less 文件时,rel 属性要设置为“stylesheet/less”。还有更重要的一点需要注意的是:LESS 源文件一定要在 less.js 引入之前引入,这样才能保证 LESS 源文件正确编译解析。 LESS 在服务器端的使用主要是借助于 LESS 的编译器,将 LESS 源文件编译生成最终的 CSS 文件,目前常用的方式是利用 node 的包管理器 (npm) 安装 LESS,安装成功后就可以在 node 环境中对 LESS 源文件进行编译。

在项目开发初期,我们无论采用客户端还是服务器端的用法,我们都需要想办法将我们要用到的 CSS 或 LESS 文件引入到我们的 HTML 页面或是桥接文件中,LESS 提供了一个我们很熟悉的功能— Importing。我们可以通过这个关键字引入我们需要的 .less 或 .css 文件。 如:

@import “variables.less”

.less 文件也可以省略后缀名,像这样:

@import “variables”

引入 CSS 同 LESS 文件一样,只是 .css 后缀名不能省略。 LESS 允许开发者自定义变量,变量可以在全局样式中使用,变量使得样式修改起来更加简单。

我们可以从下面的代码了解变量的使用及作用:

清单 3 LESS 文件 @border-color : #b5bcc7 .mythemes tableBorder{ border : 1px solid @border-color }

经过编译生成的 CSS 文件如下:

清单 4. CSS 文件 .mythemes tableBorder { border: 1px solid #b5bcc7 }

从上面的代码中我们可以看出,变量是 VALUE(值)级别的复用,可以将相同的值定义成变量统一管理起来。

该特性适用于定义主题,我们可以将背景颜色、字体颜色、边框属性等常规样式进行统一定义,这样不同的主题只需要定义不同的变量文件就可以了。当然该特性也同样适用于 CSS RESET(重置样式表),在 Web 开发中,我们往往需要屏蔽浏览器默认的样式行为而需要重新定义样式表来覆盖浏览器的默认行为,这里可以使用 LESS 的变量特性,这样就可以在不同的项目间重用样式表,我们仅需要在不同的项目样式表中,根据需求重新给变量赋值即可。

LESS 中的变量和其他编程语言一样,可以实现值的复用,同样它也有生命周期,也就是 Scope(变量范围,开发人员惯称之为作用域),简单的讲就是局部变量还是全局变量的概念,查找变量的顺序是先在局部定义中找,如果找不到,则查找上级定义,直至全局。下面我们通过一个简单的例子来解释 Scope。

清单 5. LESS 文件 @width : 20px #homeDiv { @width : 30px #centerDiv{ width : @width// 此处应该取最近定义的变量 width 的值 30px} } #leftDiv {width : @width// 此处应该取最上面定义的变量 width 的值 20px }

经过编译生成的 CSS 文件如下:

清单 6. CSS 文件 #homeDiv #centerDiv { width: 30px } #leftDiv { width: 20px } Mixins(混入)功能对用开发者来说并不陌生,很多动态语言都支持 Mixins(混入)特性,它是多重继承的一种实现,在 LESS 中,混入是指在一个 CLASS 中引入另外一个已经定义的 CLASS,就像在当前 CLASS 中增加一个属性一样。

我们先简单看一下 Mixins 在 LESS 中的使用:

清单 7. LESS 文件// 定义一个样式选择器 .roundedCorners(@radius:5px) { -moz-border-radius: @radius -webkit-border-radius: @radius border-radius: @radius } // 在另外的样式选择器中使用 #header { .roundedCorners } #footer { .roundedCorners(10px) }

经过编译生成的 CSS 文件如下:

清单 8. CSS 文件 #header { -moz-border-radius:5px -webkit-border-radius:5px border-radius:5px } #footer { -moz-border-radius:10px -webkit-border-radius:10px border-radius:10px }

从上面的代码我们可以看出:Mixins 其实是一种嵌套,它允许将一个类嵌入到另外一个类中使用,被嵌入的类也可以称作变量,简单的讲,Mixins 其实是规则级别的复用。

Mixins 还有一种形式叫做 Parametric Mixins(混入参数),LESS 也支持这一特性:

清单 9. LESS 文件// 定义一个样式选择器 .borderRadius(@radius){ -moz-border-radius: @radius -webkit-border-radius: @radius border-radius: @radius } // 使用已定义的样式选择器 #header { .borderRadius(10px)// 把 10px 作为参数传递给样式选择器 } .btn { .borderRadius(3px)// // 把 3px 作为参数传递给样式选择器 }

经过编译生成的 CSS 文件如下:

清单 10. CSS 文件 #header { -moz-border-radius: 10px -webkit-border-radius: 10px border-radius: 10px } .btn { -moz-border-radius: 3px -webkit-border-radius: 3px border-radius: 3px }

我们还可以给 Mixins 的参数定义一人默认值,如

清单 11. LESS 文件.borderRadius(@radius:5px){ -moz-border-radius: @radius -webkit-border-radius: @radius border-radius: @radius } .btn { .borderRadius }

经过编译生成的 CSS 文件如下:

清单 12. CSS 文件 .btn { -moz-border-radius: 5px -webkit-border-radius: 5px border-radius: 5px }

像 JavaScript 中arguments一样,Mixins 也有这样一个变量:@arguments。@arguments 在 Mixins 中具是一个很特别的参数,当 Mixins 引用这个参数时,该参数表示所有的变量,很多情况下,这个参数可以省去你很多代码。

清单 13. LESS 文件 .boxShadow(@x:0,@y:0,@blur:1px,@color:#000){ -moz-box-shadow: @arguments -webkit-box-shadow: @arguments box-shadow: @arguments } #header { .boxShadow(2px,2px,3px,#f36) }

经过编译生成的 CSS 文件如下:

清单 14. CSS 文件 #header { -moz-box-shadow: 2px 2px 3px #FF36 -webkit-box-shadow: 2px 2px 3px #FF36 box-shadow: 2px 2px 3px #FF36 }

Mixins 是 LESS 中很重要的特性之一,我们这里也写了很多例子,看到这些例子你是否会有这样的疑问:当我们拥有了大量选择器的时候,特别是团队协同开发时,如何保证选择器之间重名问题?如果你是 java 程序员或 C++ 程序员,我猜你肯定会想到命名空间 Namespaces,LESS 也采用了命名空间的方法来避免重名问题,于是乎 LESS 在 mixins 的基础上扩展了一下,看下面这样一段代码:

清单 15. LESS 文件 #mynamespace { .home {...} .user {...} }

这样我们就定义了一个名为 mynamespace 的命名空间,如果我们要复用 user 这个选择器的时候,我们只需要在需要混入这个选择器的地方这样使用就可以了。#mynamespace >.user。 在我们书写标准 CSS 的时候,遇到多层的元素嵌套这种情况时,我们要么采用从外到内的选择器嵌套定义,要么采用给特定元素加 CLASS 或 ID 的方式。在 LESS 中我们可以这样写:

清单 16. HTML 片段 <div id=home> <div id=top>top</div> <div id=center> <div id=left>left</div> <div id=right>right</div> </div> </div>清单 17. LESS 文件 #home{ color : blue width : 600px height : 500px border:outset #top{ border:outsetwidth : 90% } #center{ border:outsetheight : 300pxwidth : 90%#left{ border:outset float : left width : 40%} #right{ border:outset float : left width : 40%} } }

经过编译生成的 CSS 文件如下:

清单 18. CSS 文件 #home { color: blue width: 600px height: 500px border: outset } #home #top { border: outset width: 90% } #home #center { border: outset height: 300px width: 90% } #home #center #left { border: outset float: left width: 40% } #home #center #right { border: outset float: left width: 40% }

从上面的代码中我们可以看出,LESS 的嵌套规则的写法是 HTML 中的 DOM 结构相对应的,这样使我们的样式表书写更加简洁和更好的可读性。同时,嵌套规则使得对伪元素的操作更为方便。

清单 19. LESS 文件a { color: red text-decoration: none &:hover {// 有 &时解析的是同一个元素或此元素的伪类,没有 &解析是后代元素 color: black text-decoration: underline } }

经过编译生成的 CSS 文件如下:

清单 20. CSS 文件 a { color: red text-decoration: none } a:hover { color: black text-decoration: underline } 在我们的 CSS 中充斥着大量的数值型的 value,比如 color、padding、margin 等,这些数值之间在某些情况下是有着一定关系的,那么我们怎样利用 LESS 来组织我们这些数值之间的关系呢?我们来看这段代码:

清单 21 . LESS 文件 @init: #111111 @transition: @init*2 .switchColor { color: @transition }

经过编译生成的 CSS 文件如下:

清单 22. CSS 文件 .switchColor { color: #222222 }

上面的例子中使用 LESS 的 operation 是 特性,其实简单的讲,就是对数值型的 value(数字、颜色、变量等)进行加减乘除四则运算。同时 LESS 还有一个专门针对 color 的操作提供一组函数。

使用这些函数和 JavaScript 中使用函数一样。

清单 23 LESS 文件init: #f04615 #body { background-color: fadein(@init, 10%) }

经过编译生成的 CSS 文件如下:

清单 24. CSS 文件 #body { background-color: #f04615 }

从上面的例子我们可以发现,这组函数像极了 JavaScript 中的函数,它可以被调用和传递参数。这些函数的主要作用是提供颜色变换的功能,先把颜色转换成 HSL 色,然后在此基础上进行操作,LESS 还提供了获取颜色值的方法,在这里就不举例说明了。

LESS 提供的运算及函数特性适用于实现页面组件特性,比如组件切换时的渐入渐出。 同类框架还有 SASS :与 LESS 相比,两者都属于 CSS 预处理器,功能上大同小异,都是使用类似程序式语言的方式书写 CSS, 都具有变量、混入、嵌套、继承等特性,最终目的都是方便 CSS 的书写及维护。

LESS 和 SASS 互相促进互相影响,相比之下 LESS 更接近 CSS 语法。

1.Less

变量:@变量名

混合:在a类中使用b类的所有属性, .a{ .b()color:#fff}

嵌套:使用嵌套代替原始css的层叠,&表示当前选择器的父级

运算:+ - * /,可以对任何数字、颜色或变量进行运算

转义:

函数:Less 内置了多种函数用于转换颜色、处理字符串、算术运算等

命名空间和访问符

作用域:首先在本地查找变量和混合(mixins),如果找不到,则从“父”级作用域继承

注释: // 行注释,/.../块注释

导入:@import "library"可以导入一个 .less 文件,此文件中的所有变量就可以全部使用了, .less 扩展名,可以省略掉

2.css modules

CSS的规则都是全局的,任何一个组件的样式规则,都对整个页面有效。产生局部作用域的唯一方法,就是使用一个独一无二的class的名字,不会与其他选择器重名。 CSS Modules是通过哈希算法将类名编译,保证类名的唯一性。

声明全局规则:

灵活按需导入以便复用代码,避免样式全局污染,但不利于写组件单元测试

3.CSS bem规范

BEM - Block Element Modfier(块,元素,编辑器)

在选择器中用三种符号来表示扩展关系

-中划线 :仅作为连字符使用,表示某个块或者某个子元素的多单词之间的连接记号。

__ 双下划线:双下划线用来连接块和块的子元素

-- 双中划线:用来描述一个块或者块的子元素的一种状态

type-block__element--modifier

Block:不是指html中的块元素,任何独立的页面元素都可以视为一个块,这个独立的块容器有一个唯一的css类名,也就是这个块的名字

Element:属于块的某部分,任何的在Block中的DOM节点,都是一个element。在一个已知的block中,所有的element在语义上都是相等的,Block下的所有Element不考虑层级嵌套关系,扁平化处理都属于Block,即连续的__下划线只能出现一次

Modifier:用于修饰块或元素,体现在外观或行为上的改变,都可作为一个修饰器,如active状态,add/edit的操作

注意事项:

1)保证各个部分只有一级B__E--M,修饰器需要和对应的块或元素一起使用,避免单独使用。不能有 .block__el1__el2 的格式

2)仅以类名作为选择器,不使用ID或标签名来约束选择器

...import'./index.less'...<divclassName="article"><divclassName="article__body"><pclassName="article__title">title</p><buttonclassName="article__button--primary"></button><buttonclassName="article__button--success"></button></div></div>//index.less文件.article{max-width:1200px&__body{padding:20px}&__title{font-weight:700}&__button{padding:5px8px&--primary{background:blue}&--success{background:green}}}

1.编译环境不一样

Sass的安装需要Ruby环境,是在服务端处理的,而Less是需要引入less.js来处理Less

代码输出css到浏览器,也可以在开发环节使用Less,然后编译成css文件,直接放到

项目中。

2.变量符不一相

less是@,而scss是$,而且它们的作用域也不一样,less是块级作用域

3.输出设置不一样

Less没有输出设置,sass提供4种输出选项,nested,compact,compressed和expanded nested:

嵌套缩进的css代码(默认) expanded:展开的多行css代码 compact:简洁格式的css代码

compressed:压缩后的css代码

4.sass支持条件语句,可以使用if{}else{},for{}循环等等,而less不行

5.引用外部css文件

sass引用外部文件必须以开头,文件名如果以下划线形状,sass会认为该文件是一个引用文件,

不会将其编译为css文件。less引用外部文件和css中的@import没什么差异。

6.sass和less的工具库不同

sass有工具库Compass, 简单说,sass和Compass的关系有点像Javascript和jQuery的关系,

Compass是sass的工具库。在它的基础上,封装了一系列有用的模块和模板,补充强化了

sass的功能。less有UI组件库Bootstrap,Bootstrap是web前端开发中一个比较有名的前端UI

组件库,Bootstrap的样式文件部分源码就是采用less语法编写。

总结:

不管是sass,还是less,都可以视为一种基于CSS之上的高级语言,其目的是使得CSS开发更

灵活和更强大,sass的功能比less强大,基本可以说是一种真正的编程语言了,less则相对

清晰明了,易于上手,对编译环境要求比较宽松。考虑到编译sass要安装Ruby,而Ruby官网在

国内访问不了,个人在实际开发中更倾向于选择less。 (BY三人行慕课)