背景
CSS自诞生以来,其基本语法和核心机制一直没有本质上的变化,它的发展几乎是表现力层面上的提升。最开始 CSS 在网页中的作用只是辅助式性的装饰,轻便易学就是最大的需求。这也决定了 CSS 它只是一种叙述语言,而不是编程语言(编程语言具有逻辑,变量,条件语句)。但是随着互联网的发展,网站的复杂度已经不可同日而语,原生 CSS 已经让开发者越加吃力。
当一门语言的能力不足而用户的环境又不支持其它选择的时候,这门语言就会沦为“编译目标”语言。开发者将选择另一名更高级的语言来进行开发,然后编译到底层语言进行实际运行。
于是,在前端领域,CSS 预处理器就应用而生,而 CSS 这门古老的语言以另一种方式 “重新适应” 了网页开发的需求。它的基本思想是,用一种专门的编程语言,进行网页样式设计,然后再编译成正常的CSS文件。根本目的,是提高写网页样式的效率。目前主要的CSS预处理器有两种:SASS与Less。
Sass与Scss是什么关系?
Sass的缩排语法,对于写惯css前端的web开发者来说很不直观,也不能将css代码加入到Sass里面,因此sass语法进行了改良,Sass 3就变成了Scss(sassy css)。与原来的语法兼容,只是用{}取代了原来的缩进。
Less也是一种动态样式语言. 对CSS赋予了动态语言的特性,如变量,继承,运算, 函数. Less 既可以在客户端上运行 (支持IE 6+, Webkit, Firefox),也可在服务端运行 (借助 Node.js)。
如何使用Less?
最基本的方式就是在页面中引入less.js文件,就像一般使用jQuery库一样,具体步骤可以去Less官网查阅。另一种更加方便的方法就是安装IDE插件,例如在使用Sublime的时候,安装一个less插件,就可以直接在代码中使用Less,编译器自动给你转为对应的css代码。
Less的功能特性
我们使用Less是为了增加网页开发的效率,以下为Less中的功能特性:
-
文件切分
当页面越来越复杂的时候,需要加载的css文件也越来越大,我们有必要将大文件拆分开来,否则难以维护。传统的css切分方案基本上是 CSS 原生的@import
指令,或在 HTML 上加载多个 css 文件,这些方案通通不能满足性能要求。
CSS 预处理器扩展了@import
指令的能力,通过编译环节将切分后的文件重新合并为一个大文件。这一方面解决了大文件不便维护的问题,另一方面也解决了一堆小文件在加载时的性能问题。- 导入less文件可省略后缀
@import "main"; // 等价于 @import "main.less"
- reference
Less 中 最强大的特性,使用 引入的 Less 文件,但不会编译它。
/*Less*/ @import (reference) "bootstrap.less"; #wrap:extend(.navbar all){}
翻译官网:
使用@import (reference)导入外部文件,但不会添加 把导入的文件 编译到最终输出中,只引用。- once(待补充)
- multiple(待补充)
-
模块化
把文件切分的思路再向前推进一步,就是 “模块化”。一个大的 CSS 文件在合理切分之后,所产生的这些小文件的相互关系应该是一个树形结构。树形的根结节一般称作 “入口文件”,树形的其它节点一般称作 “模块文件”。入口文件通常会依赖多个模块文件,各个模块文件也可能会依赖其它更末端的模块,从而构成整个树形。
以下是一个简单的示例:
入口文件entry.styl
在编译时会引入所需的模块,生成entry.css
,然后被页面引用。)
如果你用过其它拥有模块机制的编程语言,应该已经深有体会,模块化是一种非常好的代码组织方式,是开发者设计代码结构的重要手段。模块可以很清晰地实现代码的分层、复用和依赖管理,让 CSS 的开发过程也能享受到现代程序开发的便利。 选择符嵌套
选择符嵌套是文件内部的代码组织方式,它可以让一系列相关的规则呈现出层级关系。在以前,如果要达到这个目的,我们只能这样写:
.nav {margin: auto /* 水平居中 */; width: 1000px; color: #333;}
.nav li {float: left /* 水平排列 */; width: 100px;}
.nav li a {display: block; text-decoration: none;}
这种写法需要我们手工维护缩进关系,当上级选择符发生变化时,所有相关的下级选择符都要修改;此外,把每条规则写成一行也不易阅读,为单条声明写注释也很尴尬(只能插在声明之间了)。
在 CSS 预处理语言中,嵌套语法可以很容易地表达出规则之间的层级关系,为单条声明写注释也很清晰易读:
.nav {
margin: auto; // 水平居中
width: 1000px;
color: #333;
li {
float: left; // 水平排列
width: 100px;
a {
display: block;
text-decoration: none;
}
}
}
- & 的妙用
& :代表的上一层选择器的名字 - 媒体查询(待补充)
-
变量
在变更出现之前,CSS 中的所有属性值都是 “幻数”。你不知道这个值是怎么来的、它的什么样的意义。有了变量之后,我们就可以给这些 “幻数” 起个名字了,便于记忆、阅读和理解。接下来我们会发现,当某个特定的值在多处用到时,变量就是一种简单而有效的抽象方式,可以把这种重复消灭掉。让开发者更容易实现网站视觉风格的统一,也让 “换肤” 这样的需求变得更加轻松易行。- 值变量
/*Less*/ @color: #999; @bgColor: skyblue; // 不要添加引号 @width: 50%; #wrap { color: @color; width: @width; } /*生成后的css*/ #wrap { color: #999; width: 50%; }
以
@
开头定义变量,并且使用时直接键入@
名称。在平时工作中,我们就可以把常用的变量保存到一个
文件中,这样利于代码的组织维护。- 选择器变量(待补充)
- 属性变量(待补充)
- url变量(待补充)
- 声明变量
结构: @name: { 属性: 值 ;};
使用:@name();/*Less*/ @background: {background: red;}; #main { @background(); }; @Rules: { width: 200px; hieght: 200px; border: 1px solid red; }; #con { @Rules(); } /*生成的css*/ #main { background: red; }; # con { width: 200px; height: 200px; border: 1px solid red; }
- 变量运算
加减法时 以第一个数据的单位为基准
乘除法时 注意单位一定要统一/* Less */ @width:300px; @color:#222; #wrap{ width:@width-20; height:@width-20*5; margin:(@width-20)*5; color:@color*2; background-color:@color + #111; } /* 生成的 CSS */ #wrap{ width:280px; height:200px; margin:1400px; color:#444; background-color:#333; }
- 变量作用域
就近原则
混合方法
方法犹如 声明的集合,使用时 直接键入名称即可。
/* Less */
.card { // 等价于 .card()
background: #f6f6f6;
-webkit-box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
}
#wrap{
.card;//等价于.card();
}
/* 生成的 CSS */
#wrap{
background: #f6f6f6;
-webkit-box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
}
其中 .card
与.card()
是等价的,为了表达更加清楚,我选择使用.card()
。
要点:
.
与 #
皆可作为 方法前缀。
方法后写不写 ()
看个人习惯。