CSS
(Cascading Style Sheets),层叠样式表是一种用来给HTML
或XML
定义样式的编程语言,目前最新版本为CSS3
。使用CSS有很多好处,如:可以做到网页表现与内容的分离、统一设置元素样式、对网页中的元素进行更精确的排版和控制等。但CSS也有无法递归定义、无法使用变量/表达式、及复用性不足等缺点。针对这些不足,人们推出了一些CSS预处理工具,LESS
和SASS
是使用比较广泛的两种。这些工具使我们可以用编程思想来编写CSS
,并可以帮助我们快速编译代码,及更好进行前端项目的维护。
1. LESS
LESS
是一个CSS
预处理器,它扩展了CSS
语言,添加了如:变量、混入、函数等动态语言的特性。使用LESS
可以让CSS
更容易扩展、维护及主题化。LESS
不仅可以浏览器环境中使用,也可以借助Node.js或者Rhino在服务端运行。
使用LESS
可以像下面这样编写CSS:
@base: #f938ab; .box-shadow(@style, @c) when (iscolor(@c)) { -webkit-box-shadow: @style @c; box-shadow: @style @c; } .box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) { .box-shadow(@style, rgba(0, 0, 0, @alpha)); } .box { color: saturate(@base, 5%); border-color: lighten(@base, 30%); div { .box-shadow(0 0 5px, 30%) } }
转换成CSS后:
.box { color: #fe33ac; border-color: #fdcdea; } .box div { -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); }
1.1 客户端(浏览器)安装及使用
获取 LESS
可以通过Bower
来获取LESS:
bower install less
也可以下载LESS后,直接引用。
引用LESS
客户端使用LESS
需要引用styles.less
及less.js
两个文件,.less
文件需要在.js
文件之前引用。
引用.less
样式文件,并将rel
特性设置为stylesheet/less
:
<link rel="stylesheet/less" type="text/css" href="styles.less" />
引用.js
文件:
<script src="less.js" type="text/javascript"></script>
配置
浏览器中配置LESS
,可以在引用less.js
文件前,定义一个全局的less
变量:
<!-- 引用 less.js 进行配置 --> <script> less = { env: "development", async: false, fileAsync: false, poll: 1000, functions: {}, dumpLineNumbers: "comments", relativeUrls: false, rootpath: ":/a.com/" }; </script> <script src="less.js"></script>
可以在引用时,添加自定义属性实现配置:
<script src="less.js" data-poll="1000" data-relative-urls="false"></script> <link data-dump-line-numbers="all" data-global-vars='{ myvar: "#ddffee", mystr: "\"quoted\"" }' rel="stylesheet/less" type="text/css" href="less/styles.less">
1.2 服务器(Node)中安装及使用
安装
在Node环境中,可以使用npm
命令安装:
$ npm install -g less
安装后就可以通过lessc
命令在命令行中调用:
lessc styles.less
引用
安装后,可以通过require
引用,并在服务端使用:
var less = require('less'); less.render('.class { width: (1 + 1) }', function (e, output) { console.log(output.css); });
编译为:
.class { width: 2; }
配置
可以自定义一些编译选项:
var less = require('less'); less.render('.class { width: (1 + 1) }', { paths: ['.', './lib'], // 指定 @import 路径 filename: 'style.less', // 指定用于错误显示的文件名 compress: true // 是否压缩 }, function (e, output) { console.log(output.css); });
1.3 LESS
语法
变量
LESS
允许使用@
开头的变量定义,定义后可以需要时引用它:
@nice-blue: #5B83AD; @light-blue: @nice-blue + #111; #header { color: @light-blue; }
编译后:
#header { color: #6c94be; }
这一特征在全局样式调整时非常适用,只需简单修改几个变量值就可以实现全局样式的修改。
混合
混合就是将一个格式继承到另一个样式使用。对于如下一个样式:
.bordered { border-top: dotted 1px black; border-bottom: solid 2px black; }
我们想在另一个样式中引用这个样式规则,只需要将其样式属性引入即可:
#menu a { color: #111; .bordered; } .post a { color: red; .bordered; }
混合时,也可以像函数一样定义一些参数:
.border-radius (@radius) { border-radius: @radius; -moz-border-radius: @radius; -webkit-border-radius: @radius; }
可以在其它样式中像下面这样引用:
#header { .border-radius(4px); } .button { .border-radius(6px); }
定义参时,也可以同时设置默认值:
.border-radius (@radius: 5px) { border-radius: @radius; -moz-border-radius: @radius; -webkit-border-radius: @radius; }
嵌套规则
LESS支持样式规则的嵌套使用,相当于在选择器中嵌套另一个选择器来实现继承。对于如下一个CSS:
#header { color: black; } #header .navigation { font-size: 12px; } #header .logo { width: 300px; }
在LESS中,可以像下面这样书写:
#header { color: black; .navigation { font-size: 12px; } .logo { width: 300px; } }
也可以使用伪选择器与嵌套混合使用(将&
做为当前的父选择器使用):
.clearfix { display: block; zoom: 1; &:after { content: " "; display: block; font-size: 0; height: 0; clear: both; visibility: hidden; } }
对于media
和keyframe
等可以使用相同的选择器规则,并可以其它元素中引用:
.screen-color { @media screen { color: green; @media (min-width: 768px) { color: red; } } @media tv { color: black; } }
编译后:
@media screen { .screen-color { color: green; } } @media screen and (min-width: 768px) { .screen-color { color: red; } } @media tv { .screen-color { color: black; } }
运算
可以将+
、-
、*
、/
等操作符用于数字、颜色及变量的运算:
@base: 5%; @filler: @base * 2; @other: @base + @filler; color: #888 / 4; background-color: @base-color + #111; height: 100% / 2 + @filler;
转义
转义使你可以使用任何任意的字符串作为属性或变量值。任何以~
开头的字符串都不会被LESS编译:
weird-element { content: ~"^//* some horrible but needed css hack"; }
编译结果:
.weird-element { content: ^//* some horrible but needed css hack; }
函数
LESS提供了各种用于颜色转换、字符串操作或是数学相关的函数。
如,使用percentage
增加百分比、使用saturate
改变饱合度等:
@base: #f04615; @width: 0.5; .class { width: percentage(@width); // returns `50%` color: saturate(@base, 5%); background-color: spin(lighten(@base, 25%), 8); }
命名空间与访问器
有时,你想要混合分组、或进行一些封装。你可以像下面的#bundle
定义属性集并重复使用:
#bundle { .button { display: block; border: 1px solid black; background-color: grey; &:hover { background-color: white } } .tab { ... } .citation { ... } }
接下来,只需要在#header a
中像这样引入.button
:
#header a { color: orange; #bundle > .button; }
作用域
LESS中的作用域跟其他编程语言非常相似,首先会从本地查找变量或者混合模块,如果没找到的话会去父级作用域中查找,直到找到为止:
@var: red; #page { @var: white; #header { color: @var; // white } }
变量和混合组件没有被使用之前,以代码少与上面示例的声明相同:
@var: red; #page { #header { color: @var; // white } @var: white; }
注释
LESS保留了CSS中的注释形式;同样也支持双斜线注释, 但是编译成 CSS 的时会自动过滤掉:
LESS保留了CSS中的注释形式:
/* One hell of a block style comment! */ @var: red; // Get in line! @var: white;
导入
你可以导入一个.less
文件,且导入文件中的所有变量都是可用的。导入进可以不带.less
后缀:
@import "library"; // library.less @import "typo.css";
完整LESS语法请参考:LESS语法
2. SASS
SASS
是对CSS
的扩展,在其基础上添加了嵌套规则、变量、混合、选择器继承等更多语言特性。可以使用命令行工具或WEB框架,将SASS
最终会编译为格式良好的、标准的CSS语言。
SASS
支持两种语法结构,新的主要语法为SCSS
语法,该语法是CSS的一个超集,也就是说所有CSS语法都可以SCSS中使用。SCSS使用.scss
扩展名。
第二种语法,为旧的缩进语法结构。其语法灵感来自于Haml
,主要面向喜欢CSS式的简法语法结构的人群。它使用缩进块代替CSS中原有的括号、分号等。这咱语法仍在SASS新语法结构中受支持,其扩展名为.sass
。
2.1 安装使用
SASS
基于Ruby开发,安装前应该首先安装Ruby
。然后可以使用以下命令安装:
gem install sass
更多安装方法请参考:SASS安装
安装后,就可以使用sass
命令将SASS文件转换为CSS:
sass style.scss
转换时可以指定要保存的文件名:
sass style.scss myCss.css
还可以通过--style
指定编译方式:
sass --style compressed style.scss myCss.css
SASS支持以下4种编译风格:
nested
- 默认值。嵌套缩进CSS代码expanded
- 无缩进、扩展的CSScompact
- 简洁CSS风格compressed
- 压缩后的CSS
2.2 SASS语法
变量
SASS
支持以$
开头的变量定义:
$blue: #3bbfce; $margin: 16px; .content_navigation { border-color: $blue; color: darken($blue, 10%); } .border { padding: $margin / 2; margin: $margin / 2; border-color: $blue; }
嵌套规则
SASS中支持在一个CSS规则中嵌套使用另一个:
#main p { color: #00ff00; width: 97%; .redbox { background-color: #ff0000; color: #000000; } }
其编译后:
#main p { color: #00ff00; width: 97%; } #main p .redbox { background-color: #ff0000; color: #000000; }
属性同样可以嵌套,如border-color
可以写成:
p { border: { color: red; } }
可以嵌套代码中使用$
引用父元素。可以像下面这样定义a:hover
:
a { &:hover { color: #ffb3ff; } }
运算
SASS支持code>+、-
、*
、/
等运算符。如以下样式表达式:
p { font: 10px/8px; // Plain CSS, no division $width: 1000px; width: $width/2; // Uses a variable, does division width: round(1.5)/2; // Uses a function, does division height: (500px/2); // Uses parentheses, does division margin-left: 5px + 8px/2px; // Uses +, does division font: (italic bold 10px/8px); // In a list, parentheses don't count }
编译后:
p { font: 10px/8px; width: 500px; height: 250px; margin-left: 9px; }
如果要在CSS/
中使用变量,可以像下面这样:
p { $font-size: 12px; $line-height: 30px; font: #{$font-size}/#{$line-height}; }
编译后:
p { font: 12px/30px; }
继承
SASS中选择器可以通过@extend
实现继承:
.hoverlink { @extend a:hover; }
继承以上选择器:
.hoverlink { @extend a:hover; } a:hover { text-decoration: underline; }
编译后:
a:hover, .hoverlink { text-decoration: underline; }
混合
混合(Mixin
)使我们可以定义可复用的代码块。定义混合使用@mixin
关键字:
@mixin large-text { font: { family: Arial; size: 20px; weight: bold; } color: #ff0000; }
混合语法中同样可以包含子选择器:
@mixin clearfix { display: inline-block; &:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } * html & { height: 1px } }
定义混合后,通过@include
引入即可实现代码的复用:
.page-title { @include large-text; padding: 4px; margin-top: 10px; }
编译后:
.page-title { font-family: Arial; font-size: 20px; font-weight: bold; color: #ff0000; padding: 4px; margin-top: 10px; }
混合时可以添加参数:
@mixin left { float: left; margin-left: 10px; }
可以像下面这样传入参数:
div { @include left(20px); }
自定义参数可以使用默认值:
@mixin left($value 10px) { float: left; margin-left: $value; }
函数
SASS支持很多函数。
如,使用颜色函数:
lighten(#cc3, 10%) // #d6d65c darken(#cc3, 10%) // #a3a329 grayscale(#cc3) // #808080 complement(#cc3) // #33c
也可以使用@function
关键字自定义函数:
@function double($n) { @return $n * 2; } #sidebar { width: double(5px); }
语法支持
可以使用@if
及@else
进行条件判断:
@if lightness($color) > 30% { background-color: #000; } @else { background-color: #fff; }
也支持@for
、@while
、@each
等循环语法:
@for $i from 1 through 3 { .item-#{$i} { width: 2em * $i; } }
@each $animal in puma, sea-slug, egret, salamander { .#{$animal}-icon { background-image: url('/images/#{$animal}.png'); } }
文件导入
通过@import
命令可以导入另一个文件:
@import "foo.scss";
导入时可以省略扩展名:
@import "foo";
SASS支持的导入文件类型有:css
文件、http://
开头的URI、url()
函数导入或SASS文件。
注释
SASS支持CSS原生的/* 注释内容 */
和//
两种注释方式:
/* 这个注释 * 是一个多行注释 * 这是一个CSS风格的注释 */ body { color: black; } // 这是一个单行注释 // 这种注释只在SASS文件中 // 编译后刚会被忽略 a { color: green; }