本篇内容梳理自如下几个来源:css
感谢大佬们的分享。html
什么是 CSS 预处理?为何要有 CSS 预处理?node
这里就讲讲这两个问题,写过 CSS 应该就会比较清楚,虽然我才刚入门,但在写一些练手时就已经有点感受了:写 CSS 后,很难维护,维护基本要靠注释来,并且因为 HTML 文档中标签的嵌套层次复杂,致使写 CSS 的选择器时也很费劲,尤为是在后期为某部分标签新增样式时,总会不知道到底应该在 CSS 文件中哪里写这个选择器,这个选择器是否会与前面冲突。git
最有感受的一点是,CSS 代码基本无法复用,一个页面一份 CSS,每次都须要重写,只是不少时候,能够直接去旧的里面复制粘贴。github
有这么些问题是由于 CSS 自己并非一门编程语言,它只是一个标记语言,静态语言,不具有编程语言的特性,因此写容易,但维护会比较难。web
这个时候,CSS 预处理器就出现了,其实应该是说 Sass 和 Less 这类语言出现了。npm
Sass 和 Less 这类语言,其实能够理解成 CSS 的超集,也就是它们是基于 CSS 本来的语法格式基础上,增长了编程语言的特性,如变量的使用、逻辑语句的支持、函数等。让 CSS 代码更容易维护和复用。编程
但浏览器最终确定是只认识 CSS 文件的,它并没有法处理 CSS 中的那些变量、逻辑语句,因此须要有一个编译的过程,将 Sass 或 Less 写的代码转换成标准的 CSS 代码,这个过程就称为 CSS 预处理。json
因此,CSS 预处理器其实只是一个过程的称呼,主要工做就是将源代码编译并输出标准的 CSS 文件,而这个源代码能够用 Sass 写,也能够用 Less,固然还有其余不少种语言。数组
那么,到底哪种语言好,我还没能力来讨论,反正存在即有理,每种语言总它的优缺点、总有它的适用场景。
下面,主要就来介绍下其中的两种语言:Less 和 Sass。
我以为,掌握 CSS 预处理的关键,其实也就两点,一是掌握语言的语法、二是清楚怎么编译成标准的 CSS 文件;语法基本都不会很难,编译通常须要配置一些环境,由于我使用的开发工具是 WebStrom,因此会介绍下 WebStrom 上的配置。
Less 写的 CSS 文件后缀名为 .less
,但浏览器并不认识 less 文件,因此最后须要转换成 css 文件,有两种方式:
这种方式,不须要配置任何其余环境,只须要下载 less.js,并在项目中使用便可,但有几点须要注意:
<head> <!--link标签须要设置 rel=stylesheet/less, less.js的加载须要放在全部 link 标签后面--> <link rel="stylesheet/less" type="text/css" href="css/src/main.less"/> <link rel="stylesheet/less" type="text/css" href="css/src/test.less"/> <script src="js/lib/less.js"></script> </head>
HTML 文档经过 link 标签引入 less 文件时,须要将 link 标签的 rel 属性设置为 stylesheet/less,不然无效;
并且,用 <script> 标签加载 less.js 的代码须要放在最后,即全部用 link 标签引入 less 文件的后面,由于 less.js 文件加载成功后就会去将 less 转成 css 标准样式,在 <script> 标签后面才用 link 标签引入的那些 less 文件就没法被转换了。
less.js 下载地址:https://github.com/less/less.js/releases
第一种方式,虽然便捷,但会让页面的渲染多了一个转换步骤,延长页面渲染时长,因此,还能够用第二种方式,直接在本地将 less 转成 css 文件后,项目直接使用转换后输出的 css 文件。
假设你已经在电脑上安装了 node.js 了,若是尚未,先去网上自行搜索下教程,不少,也很快。
首次使用须要先安装 less,打开终端,执行下述命令:
npm install -g less
安装完后,就可使用 lessc 命令,如:
lessc main.less main.css
这是最简单的用法,将 main.less 文件编译输出 main.css;还有其余高级的用法,好比顺便压缩 css 文件,输出 .min.css 文件等等。
我是比较习惯使用第二种方式,也就是在本地就将 less 文件转成 css 文件,项目里是直接使用转换后输出的 css 文件了,并且我用的开发工具是 WebStrom,因此能够借助它,省去了每次本身输命令的操做:
第一步:在项目根目录下执行 npm init -y
初始化项目,初始化完项目后,根目录会生成 package.json 文件;
第二步:打开 package.json,在里面的 scripts 字段,根据你的项目结构,输入脚本命令;
第三步:点击 scripts 旁边的三角形按钮,就能够自动执行脚本命令,完成转换工做;
第四步:(可选)若是嫌每次都须要本身手动点击按钮麻烦,能够将这项工做添加进 File Watcher 功能中,每次文件改动就会自动执行脚本命令,完成转换,具体参考上一篇,或者自行搜索,很简单。
这是例子的项目结构:
src 目录中存放 less 文件,dist 目录中存放转换后输出的 css 文件,因此,个人 package.json 里的脚本命令以下:
具体的脚本命令可根据实际需求,实际项目结构,自行决定。
好了,清楚了 less 文件的两种使用方式后,就能够来学习语法了,这样在学习语法过程当中,就能够随时进行转换,查看 less 书写的代码,最终转换的 css 代码是什么样的,这样比较着学习比较容易掌握。
经过 @变量名:
来定义变量,经过 @变量名
使用变量,其实本质上是常量了,如:
@width: 10px; /*定义变量*/ @height: @width + 10px; /*使用变量,和逻辑语句*/ #header { width: @width; /*使用变量*/ height: @height; }
转换成 CSS 文件:
/*定义变量*/ /*使用变量,和逻辑语句*/ #header { width: 10px; /*使用变量*/ height: 20px; }
上个例子中,转换后的注释也还保留着,这是由于 less 和 css 都支持 /* */
的注释方式,因此这种会保留,但若是是 //
,这种只有在 less 中支持,css 不支持,那么这种注释就不会保留,验证下:
/*这是注释1*/ //这是注释2
转换成 css 文件:
/*这是注释1*/
因此,在 less 中使用注释时,须要注意下,哪些是想保留,哪些是不想保留的。
也有的文章里翻译成混入,还有的文章直接保留单词,不作翻译,多是以为中文翻译不可以很好的表达意思吧。
先说有这么种场景:有时候写在某个选择器中的属性样式,在其余选择器中也须要,因此一般是直接将那部分复制粘贴过来使用。
而 less 的 Mixins 容许你在某个选择器内,直接使用其余选择器内的属性样式,因此中文翻译才有混合,或混入之说,其实也就是将其余的属性样式混合到当前选择器中。
看个例子就明白了:
.class1 { //类选择器 class1 的属性样式 width: 10px; height: 20px; } .class2(@color: #fff) { //定义了一个模板样式,相似于函数的做用 background-color: @color; } #id1() { //定义了一个模板样式,相似于函数做用 border: 1px solid #ff22ff; } .mian { .class1; //直接使用其余选择器定义的属性样式 .class2(#f2f); //使用模板样式,传入参数 #id1; //使用模板样式,不传参时,括号可省略 }
转换后的 CSS 文件:
.class1 { width: 10px; height: 20px; } .mian { width: 10px; height: 20px; background-color: #f2f; border: 1px solid #ff22ff; }
能够注意对比源代码和转换后的代码,本来就定义好的基本选择器,如 .class1
,可直接在其余选择器内经过 .calss1
将它内部的属性样式都复制过来。
也能够在基本选择器后面加上 ()
括号,这样一来,这个就会被当作模板处理,做用相似于函数,可接收参数,使用时就相似于调用函数那么使用,若是不传参,调用时也能够将括号省略。既然是做为函数使用,那么它们存在的意义就只是被调用,因此转换后的 CSS 中并不会存在这个函数。
另外,有的文章中,对 Mixins 的解释是说,在 class 中使用 class,但上面的例子中也测试了,class 中也是可使用其余 id 选择器的属性样式的,因此应该不只限于 class 类选择器,但不能用于组合选择器中。
我对于命名空间的理解:属于 less 本身的命名空间,也就是这些代码并不会在转换后的 CSS 文件中出现,由于它只属于 less。
因此,其实也就是上述例子中,相似函数存在的那些模板选择器,当在书写选择器时,在其后面增长 ()
括号,则表示这个选择器只属于 less 的命名空间,转成 CSS 后并不会出现。k
在写 CSS 时,组合选择器常常写得很复杂,由于 HTML 里的标签嵌套层次自己就很复杂,并且组合选择器写完也不是可以很明显的表示出它的目的,因此 less 容许依据 HTML 中的嵌套层次来书写,不用去记那么多组合选择器的规则,如:
body { font-size: 16px; .content { .banner { ul { img { width: 700px; height: 300px; &:hover { width: 800px; height: 300px; } } } } } }
转换成 CSS 文件:
body { font-size: 16px; } body .content .banner ul img { width: 700px; height: 300px; } body .content .banner ul img:hover { width: 800px; height: 300px; }
也就是,子孙后代的组合选择器规则能够不用去记,直接根据 HTML 文档中标签的嵌套层次来书写便可,这样便于后期维护,若是要对某个标签新增某些样式,也知道该去哪里找。
有一点须要注意的是,相似 a:hover
这种伪类选择器,须要加一个 &
符号。
less 容许在代码中进行一些简单的加、减、乘、除基本运算,结合变量的使用,可进行一些字体、颜色等的动态运算效果。
@border: 1px; @color: #fff; #header { color: @color * 0.5; border-width: @border @border*2 @border*3 @border*4; }
转换成 CSS 后:
#header { color: #808080; border-width: 1px 2px 3px 4px; }
一般,变量和运算都是用于对颜色、大小等进行计算。
less 内置了一些基础函数,可用于转换颜色、处理字符串、算术运算等,这里列举一些函数:
color("#aaa"); //输出 #aaa, 将字符串的颜色值转换为颜色值 image-size("file.png"); //输出 => 10px 10px,获取图片文件的宽高信息 //image-with("file.png"); image-height("file.png"); 获取图片文件宽高 convert(9s, "ms"); //输出 => 9000ms,单位换算,例如对 m,cm,mmin,pt,pc的换算 @size: if((true), 1px, 0px); //if函数,第一个参数为条件,知足则返回第二个参数,不知足返回第三个参数 if(not (true), 1px, 0px); //非语句, not if((true) and (true), 1px, 0px); //逻辑与语句, and if((false) or (true), 1px, 0px); //逻辑或语句, or //处理数组 @list: "banana", "tomato", "potato", "peach"; length(@list); // 输出 => 4 extract(@list, 3); //输出 => potato,注意第一个不是从 0 开始计算 //类型判断 isnumber(#ff0); // false isstring("234"); // true iscolor(#ff0); // true isXXX ...
内置函数不少,用途也不少,覆盖了基本算术运算、逻辑语句、颜色计算、字符串处理等等,须要用时再查手册吧。
做用域很好理解,就是相似 JavaScript 中的变量做用域,由于在 less 中都是经过 @变量名:
来定义变量的,后定义的会覆盖掉前定义的,但当在不一样嵌套层次中定义同一变量时,就存在局部变量和外部变量之分,内部变量并不会覆盖掉外部变量。
并且,less 的变量定义也有相似 JavaScript 中的提早特性,如:
@var: red; #aaa { color: @var; // yellow,由于后面定义的 @var:yellow 将 @var:red 覆盖掉了 } #page { #header { color: @var; // white,内部变量不影响外部变量 } @var: white; } @var: yellow; #ppp { color: @var; //yellow }
看看转换成 CSS 后:
#aaa { color: yellow; } #page #header { color: white; } #ppp { color: yellow; }
若是某份 less 文件是能够复用的,那么可使用 @import
命令将其所有引入使用。
@import "main";
最后在 test.css 里会汇合 main.less 里的代码。
以上,只是介绍 less 的基础语法,还有更多详细、复杂的语法用途,须要时再翻阅文档吧。
Sass 相比于 Less 功能会更强大,但也更复杂。
Sass 和 Scss 本质是一家,Sass 早期版本的文件后缀名是 .sass
,从 Sass 3 以后,由于修改了一些特性语法,Sass 更增强大且易使用,从这个版本以后的文件后缀名改为了 .scss
,因此 Scss 其实 Sass 的新版本的称呼,但二者本质上没太大区别。
Scss 是基于 Sass 的语法基础上,修改了一部分的语法。好比早期的 Sass 是经过换行和缩进如:
#sidebar width: 30% background-color: #faa
这种语法格式跟 CSS 不一致,让使用者会很不习惯,Scss 以后就换成用分号和括号了:
#sidebar { width: 30%; background-color: #faa; }
Sass 不像 Less 同样能够直接借助 less.js 来进行转换,它是基于 Ruby 运行环境,因此电脑上须要先安装 Ruby,而后才能有办法将 Sass 文件转成 CSS。
Ruby 下载地址:https://rubyinstaller.org/downloads/
由于是 exe 文件,下载完直接按提示安装就能够了,安装后打开终端,执行 gem 命名安装 Sass:
gem install sass
安装完 Sass 后,就能够经过 scss 命令来进行转换工做了,如:
scss main.scss main.css
上述命令中,scss 换成 sass 也能够,但注意,scss 或 sass 命令是基于 Ruby 环境下运行的命令,由于电脑上已经安装过 Ruby 了,也经过 Ruby 安装了 Sass,因此才能够在终端里直接执行 scss 命令。
而相似于 Less 中说到的,WebStrom 能够借助 package.json 里的 scripts 来手动运行脚本命令,这有个前提,就这些脚本命令是运行在 node.js 环境上的,因此若是你直接将上述 scss 命令配置到 package.json 的 script 里,你会发现,是运行不了的。
要解决这个问题,让 WebStrom 可以运行 sass 命令来处理转换工做有两种方式:
这种方式下,每次配置的文件变更时,会自动生成对应的 css 文件,转换工做会自动实时进行。但若是不习惯这种方式,想要每次编写完 scss 代码后,手动来触发转换工做,那么能够选择第二种方式:
在终端里执行 npm install -g sass
,这样就能够相似配置 less 那样的步骤来使用 sass 命令了,在 package.json 里配置相关命令,而后手动点击脚本的运行便可。
但 npm 安装的 sass 跟在 Ruby 下安装的 sass 是否有和区别,我不清楚,用段时间,若是有啥问题再来讲说。
并且,对于选择使用 Sass,刚接触可能会有些困惑,是应该使用哪一个后缀名的文件,命令是该用 sass 仍是 scss 来进行转换,我也有这个困惑,但感受好像并无什么区别,先试着用段时间,之后熟悉了再来说讲。
最后,Sass 虽然有 .sass
和 .scss
两种后缀名的文件,但建议使用 .scss
,由于前者的语法跟 CSS 很不同,使用起来会有些不习惯,固然若是你有 Ruby 基础的话,可能会比较喜欢这种。我我的会选择后者。
语法方面,大部分相似于 Less,但就细节方面可能有些不同,还有,支持更多更强大的功能吧。
上面介绍的 Less 的基础语法、基础功能,Sass 也基本所有支持,也差不了多少,因此下面就不一个个来介绍了,详细的到开头声明部分给的中文网连接中去查阅便可。
下面就主要列一些不一样的地方:
Sass 中的变量用 $变量名:
定义,用 $变量名
使用,其他跟 Less 差不了多少。
Less 中的变量分局部做用域和全局做用域,但在 Sass 中,不一样版本,做用域范围并不同,摘抄一段原文中描述:
Sass 中变量的做用域在过去几年已经发生了一些改变。直到最近,规则集和其余范围内声明变量的做用域才默认为本地。若是已经存在同名的全局变量,则局部变量覆盖全局变量。从 Sass 3.4 版本开始,Sass 已经能够正确处理做用域的概念,并经过建立一个新的局部变量来代替。
Less 中并不支持条件语句,固然,能够经过内置函数 if 以及 and,or,not 这些来模拟条件语句。
在 Sass 中是支持条件语句的,但也不是像其余编程语言直接 if 这样经过保留字来编写,须要加个 @
符合,如:
@if $support-legacy { // … } @else { // … }
教程中给了几条准则要求:
@if
以前添加空行;{
)后换行;@else
语句和它前面的右闭大括号(}
)写在同一行;}
)后添加空行,除非下一行仍是右闭大括号(}
),那么就在最后一个右闭大括号(}
)后添加空行。另外,教程中也说了:
除非你的代码中有偏复杂的逻辑,不然不必在平常开发的样式表中使用条件语句。实际上,条件语句主要适用于库和框架。
其余区别,等用段时间,熟悉了再来说讲。
Sass 有一点比 Less 有优点的就是,目前有不少稳定且热门的基于 Sass 编写的框架库,好比:Compass、Bourbon 和 Susy 等。
这些框架库就相似于 jQurey 和 JavaScript 关系,对 Sass 进行了一层封装,让编写 Sass 代码的人,能够极为简便的开发,我还没用过,就不过多介绍了。
你们好,我是 dasu,欢迎关注个人公众号(dasuAndroidTv),公众号中有个人联系方式,欢迎有事没事来唠嗑一下,若是你以为本篇内容有帮助到你,能够转载但记得要关注,要标明原文哦,谢谢支持~