Sass是一种CSS预处理器。它可以让开发者少写一些CSS代码。
- 安装Sass
Sass是用Ruby写成的,可以使用Ruby Gems安装。
gem install sass
安装完成后查看Sass版本:
sass -v
此时最新版本是Sass 3.2.12 (Media Mark)
- 编译CSS
Sass文件后缀名是.scss,意为(Sassy CSS)
$ sass input.scss output.css
上面这个命令将input.scss文件编译为output.css文件。
还可以在编译时加上参数,比如–style。此参数表明编译后的css风格。
SASS提供四个编译风格的选项:
1. nested:嵌套缩进的css代码,它是默认值。
2. expanded:没有缩进的、扩展的css代码。
3. compact:简洁格式的css代码。
4. compressed:压缩后的css代码。
如:
$ sass --style compressed input.scss output.css
将源文档编译为压缩的css代码。
你也可以让Sass监听某个文件或目录,一旦源文件有变动,就自动生成编译后的版本。
1 | # 监听单个文件: |
- CSS扩展
1.嵌套规则
1 | #main p { |
将被编译为:
1 | #main p { |
.redbox
为p
的后代元素。
1 | #main { |
将被编译为:
1 | #main { |
这样可以减少很多重复输入。
2.父元素选择符&
1 | a { |
将被编译为:
1 | a { |
上例中&被替换为当前元素的父元素。
&可以用在深沉嵌套里面,它可以被正确地替换为当前元素的父元素。
例如:
1 | #main { |
将被编译为:
1 | #main { |
这里&被替换为a
。
3.属性嵌套
比如我们有一系列的属性如:font-family, font-style, font-weight, font-size等等,它们都有相同的前缀font
,那么可以这样写:
1 | font: { |
注释
Sass支持两种注释:/ /(多行注释) 和 //(单行注释)
在编译时,多行注释会保留到css文件中,而单行注释则不予保留。比如:
/* This comment is * several lines long. * since it uses the CSS comment syntax, * it will appear in the CSS output. */ body { color: black; } // These comments are only one line long each. // They won't appear in the CSS output, // since they use the single-line comment syntax. a { color: green; }
编译为:
/* This comment is * several lines long. * since it uses the CSS comment syntax, * it will appear in the CSS output. */ body { color: black; } a { color: green; }
- SassScript 脚本
Sass脚本支持变量,运算和函数等等。
1.变量
SassScript变量以$符号开头。
定义一个变量:
$width: 5em; //语句以分号(;)结尾。
然后就可以引用它。
1 | #main { |
2.数据类型
SassScript支持6种主要的数据类型:
- 数值(1.2, 13, 10px等)
- 文本字符串,可以加或不加引号(“foo”, “bar”, baz等)
- 颜色(blue, #04a3f9, rgba(255, 0, 0, 0.5)等)
- 布尔值(true, false)
- nulls(null)
- 列表值,由空格或者逗号分割(1.5em 1em 0.2em, Helvetica, Arial, sans-serif)
3.运算符
SassScript支持标准的数学运算符:(+, -, *, /, %)
1 | p { |
将被编译为:
1 | p { |
除法运算符(/)比较特殊。css中有些属性可以使用(/)符号,比如font: 10px/1.5
,那么SassScript中什么情况表示除法呢?有3中情况:
1.如果表达式含有变量
2.如果使用括号()包围
3.如果表达式作为另一个算数运算的值
如下:
1 | p { |
将被编译为:
1 | p { |
如果想使用变量而不使用除法运算符,需要将变量放在#{}里面。
如:
1 | p { |
将被编译为:
1 | p { |
- 字符串操作:
+
可以用来连接字符串。
1 | p { |
将被编译为:
1 | p { |
如果带引号的字符串+
不带引号的字符串则结果为带引号的字符串;如果不带引号的字符串+
带引号的字符串,结果为不带引号的字符串。总结起来就是:谁在左边听谁的!
举个例子:
1 | p:before { |
将被编译为:
1 | p:before { |
- 差值运算符
SassScript变量还可以用于选择器和属性名,只需用#{}包围即可。如:
1 | $name: foo; |
将被编译为:
1 | p.foo { |
//
#main {
content:
}
1 |
|
#main {
content: $content; // “Non-null content”
}
1 |
|
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}
1 | 如果想要.seriousError 含有.error的属性,你必须将.seriousError和.error写在一起,像这样: |
.error, .seriousError {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}
1 | 使用@extend则可以写为: |
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
1 | 这样,.error 的每个属性都会应用到.seriousError。 |
.error {
border: 1px #f00;
background-color: #fdd;
}
.error.intrusion {
background-image: url(“/image/hacked.png”);
}
.seriousError {
@extend .error;
border-width: 3px;
}
1 |
|
.error, .seriousError{
border: 1px #f00;
background-color: #fdd;
}
.error.intrusion, .seriousError.intrusion{
background-image: url(“/image/hacked.png”);
}
.seriousError {
border-width: 3px;
}
1 |
|
.error {
border: 1px #f00;
background-color: #fdd;
}
.attention {
font-size: 3em;
background-color: #ff0;
}
.seriousError {
@extend .error; //继承.error
@extend .attention; //继承.attention
border-width: 3px;
}
1 | 将被编译为: |
.error, .seriousError {
border: 1px #f00;
background-color: #fdd;
}
.attention, .seriousError {
font-size: 3em;
background-color: #ff0;
}
.seriousError {
border-width: 3px;
}
1 |
|
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
.criticalError {
@extend .seriousError;
position: fixed;
top: 10%;
bottom: 10%;
left: 10%;
right: 10%;
}
1 |
|
.error, .seriousError, .criticalError {
border: 1px #f00;
background-color: #fdd;
}
.seriousError, .criticalError {
border-width: 3px;
}
.criticalError {
position: fixed;
top: 10%;
bottom: 10%;
left: 10%;
right: 10%;
}
1 |
|
p {
@if 1 + 1 == 2 { border: 1px solid; }
@if 5 < 3 { border: 2px dotted; }
@if null { border: 3px double; }
}
1 |
|
p {
border: 1px solid;
}
1 |
|
@for
}
1 |
|
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
.item-3 {
width: 6em;
}
1 |
|
@each
background-image: url(‘/images/#{$animal}.png’);
}
}
1 |
|
.puma-icon {
background-image: url(‘/images/puma.png’);
}
.sea-slug-icon {
background-image: url(‘/images/sea-slug.png’);
}
.egret-icon {
background-image: url(‘/images/egret.png’);
}
.salamander-icon {
background-image: url(‘/images/salamander.png’);
}
1 |
|
.item-#{
}
1 |
|
.item-6 {
width: 12em;
}
.item-4 {
width: 8em;
}
.item-2 {
width: 4em;
}
1 |
|
@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
}
1 |
|
.page-title {
@include large-text;
padding: 4px;
margin-top: 10px;
}
1 |
|
.page-title {
font-family: Arial;
font-size: 20px;
font-weight: bold;
color: #ff0000;
padding: 4px;
margin-top: 10px;
}
1 |
|
@mixin compound {
@include highlighted-background;
@include header-text;
}
@mixin highlighted-background { background-color: #fc0; }
@mixin header-text { font-size: 20px; }
1 |
|
@mixin sexy-border(
border: {
color:
style: dashed;
}
}
p { @include sexy-border(blue, 1in); }
1 |
|
p {
border-color: blue;
border-width: 1in;
border-style: dashed;
}
1 |
|
@mixin sexy-border(
border: {
color:
style: dashed;
}
}
p { @include sexy-border(blue); } // 没有传递值给
h1 { @include sexy-border(blue, 2in); } //$width: 2in
1 |
|
p {
border-color: blue;
border-width: 1in;
border-style: dashed;
}
h1 {
border-color: blue;
border-width: 2in;
border-style: dashed;
}`