1. 特色功能 (Features)
2 语法格式 (Syntax)
.scss
-CSS3 语法在 SCSS 中都是通用的
.sass
-使用 “缩进” 代替 “花括号” 表示属性属于某个选择器,用 “换行” 代替 “分号” 分隔属性
任何一种格式可以直接带入(@import
)到另一种格式中使用,或者通过sass-convert
命令行工具转换成另一种格式:
# Convert Sass to SCSS
$ sass-conovert style.sass style.scss
3 使用Sass(Using Sass)
使用方式:
- 作为命令行工具
- 作为独立的Ruby模块
- 作为Rack-enabled框架的插件
先安装Sass gem(Windows系统需要先安装Ruby):
gem install sass
监视单个Sass文件,每次修改并保存时自动编译:
sass --watch input.scss:output.css
监视整个文件夹:
sass --watch app/sass:public/stylesheets
3.1. Rack/Rails/Merb Plugin
3.2. 缓存 (Caching)
单独使用 Sass,缓存内容保存在 .sass-cache
文件夹中;在 Rails 和 Merb 项目中缓存文件保存在 tmp/sass-cache
文件夹中(可通过 :cache_location
修改路径)。
禁用缓存可将 :cache
设为 false
。
3.3. 配置选项 (Options)
3.4. 判断语法格式 (Syntax Selection)
Sass 命令行工具根据文件的拓展名判断所使用的语法格式,没有文件名时 sass
命令默认编译 .sass
文件,添加 --scss
选项或者使用 scss
命令编译 SCSS 文件。
3.5. 编码格式 (Encodings)
4. CSS 功能拓展 (CSS Extensions)
4.1. 嵌套规则 (Nested Rules)
#content {
article {
h1 { color: #333 }
p { margin-bottom: 1.4em }
}
aside { background-color: #EEE }
}
4.2. 父选择器 &
(Referencing Parent Selectors: &)
用法1:
article a {
color: blue;
&:hover { color: red }
}
用法2:
在父选择器之前添加选择器
#content aside {
color: red;
body.ie & { color: green }
}
4.3. 属性嵌套 (Nested Properties)
nav {
border: {
style: solid;
width: 1px;
color: #ccc;
}
}
或
nav {
border: 1px solid #ccc {
left: 0px;
right: 0px;
}
群组选择器的嵌套;
.container {
h1, h2, h3 {margin-bottom: .8em}
}
子组合选择器和同层组合选择器:>、+和~;article {
~ article { border-top: 1px dashed #ccc }
> section { background: #eee }
dl > {
dt { color: #333 }
dd { color: #555 }
}
nav + & { margin-top: 0 }
4.4. 占位符选择器 %foo (Placeholder Selectors: %foo)
与常用的 id 与 class 选择器写法相似,只是 # 或 . 替换成了 %
。必须通过 @extend
指令调用。
%div01 {}
.div02{
@extend %div01
}
占位选择器%
只有 被继承 才会被编译,否则,不会被编译。
5. 注释 /* / 与 // (Comments: / */ and //)
Sass 支持标准的 CSS 多行注释 /* */
,以及单行注释 //
,前者会 被完整输出到编译后的 CSS 文件中,而后者则不会。
标准注释格式/* ... */
出现在原生css不允许的地方,这些注释也会被抹掉。
6. SassScript
6.1. Interactive Shell
命令行输入sass -i
,然后输入SassScript测试查看输出结果
$ sass -i
“Hello,Sassy World!”
“Hello,Sassy World!”1px + 1px + 1px
3px#777 + #888
white
6.2. 变量 $ (Variables: $)
使用$
符号来标识变量
$highlight-color: #F90;
直接使用即调用变量:
border: 1px solid $highlight-color;
变量支持局部变量、全局变量
局部变量转换为全局变量可以添加 !global
声明:
$width: 5em !global;
变量名用中划线还是下划线分隔
中划线或下划线,这两种用法相互兼容,$link-color
和$link_color
其实指向的是同一个变量
多值变量
$paddings: 3px 5px 10px 8px;
body{
padding-left:nth($paddings, 1);
}
或
$maps: (color: red, borderColor: blue);
footer {
background-color: map-get($maps,color);
}
6.3. 数据类型 (Data Types)
- 数字,
1, 2, 13, 10px
- 字符串,有引号字符串与无引号字符串,
"foo", 'bar', baz
- 颜色,
blue, #ffffff, rgba()
- 布尔型,
true,false
- 空值,
null
- 数组,
1.5em 1em 0 2em, Helvetica, Arial, sans-serif
- maps, 相当于 JavaScript 的 object,
(key1: value1, key2: value2)
6.4. 运算 (Operations)
所有数据类型均支持相等运算 ==
或 !=
6.4.1. 数字运算 (Number Operations)
+, -, *, /, %
,如果必要会在不同单位间转换值
关系运算 <, >, <=, >=
也可用于数字运算
6.4.1.1. 除法运算 / (Division and /)
/
在 CSS 中通常起到分隔数字的用途,SassScript同时也赋予了 /
除法运算的功能。
以下三种情况 /
将被视为除法运算符号:
- 如果值,或值的一部分,是变量或者函数的返回值,
font: 18px/1.2 Helvetica,Arial;
分隔;font: $f/1.2 Helvetica,Arial;
除法 - 如果值被圆括号包裹
- 如果值是算数表达式的一部分
如果需要使用变量,同时又要确保/
不做除法运算而是完整地编译到 CSS 文件中,只需要用#{}
插值语句将变量包裹。
p{
font: #{$f}/#{2} Helvetica,Arial;;
}
6.4.2. 颜色值运算 (Color Operations)
分段计算,也就是分别计算红色,绿色,以及蓝色的值:
p {
color: #010203 + #040506;
}
计算01 + 04 = 05
02 + 05 = 07
03 + 06 = 09
编译为
p {
color: #050709; }
如果颜色值包含 alpha channel
(rgba 或 hsla 两种颜色值),必须拥有相等的 alpha
值才能进行运算,因为算术运算不会作用于 alpha 值。
颜色值的 alpha channel 可以通过 opacify
或 transparentize
两个函数进行调整
$translucent-red: rgba(255, 0, 0, 0.5);
p {
color: opacify($translucent-red, 0.3);
background-color: transparentize($translucent-red, 0.25);
}
IE 滤镜要求所有的颜色值包含 alpha 层,而且格式必须固定 #AABBCCDD
,使用 ie_hex_str
函数可以很容易地将颜色转化为 IE 滤镜要求的格式。
$translucent-red: rgba(255, 0, 0, 0.5);
$green: #00ff00;
div {
filter: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr='#{ie-hex-str($green)}', endColorstr='#{ie-hex-str($translucent-red)}');
}
6.4.4. 布尔运算 (Boolean Operations)
SassScript 支持布尔型的 and
or
以及 not 运算。
6.4.5. 数组运算 (List Operations)
数组不支持任何运算方式,只能使用 list functions 控制。
6.5. 圆括号 (Parentheses)
圆括号可以用来影响运算的顺序:
p {
width: 1em + (2em * 3);
}
6.6. 函数 (Functions)
6.7. 插值语句 #{} (Interpolation: #{})
通过 #{}
插值语句可以在选择器或属性名中使用变量:
$name: foo;
$attr: border;
p.#{$name} {
#{$sttr}-color: blue;
}
#{}
插值语句也可以在属性值中插入 SassScript,可以避免 Sass 运行运算表达式,直接编译 CSS。
p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height};
}
6.8. & in SassScript
6.9. 变量定义 !default (Variable Defaults: !default)
变量结尾添加 !default
给一个为通 !default
声明赋值的变量赋值, 如果变量已经被赋值,那就用它声明的值,否则就用这个默认值。
$content: "First content";
$content: "Second content?" !default;
$new_content: "First time reference" !default;
#main {
content: $content;
new-content: $new_content;
}
编译为
#main {
content: "First content";
new-content: "First time reference"; }
变量是 null 空值时将视为未被 !default 赋值。
$content: null;
$content: "Non-null content" !default;
#main {
content: $content;
}
7. @-Rules 与指令 (@-Rules and Directives)
7.1. @import
@import
的功能,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用。
Sass 在当前地址,或 Rack, Rails, Merb 的 Sass 文件地址寻找 Sass 文件。
设定其他地址,可以用 :load_paths
选项,或者在命令行中输入--load-path
命令。
以下情况下,@import
仅作为普通的 CSS 语句,不会导入任何 Sass 文件。
- 文件拓展名是
.css
; - 文件名以
http://
开头; - 文件名是
url()
; @import
包含 media queries。
没有指定拓展名,Sass 将会试着寻找文件名相同,拓展名为.scss
或.sass
的文件并将其导入,可以省略.sass
或.scss
文件后缀。
Sass 允许同时导入多个文件:
@import "rounded-corners", "text-shadow";
也可以使用 #{}
插值语句,只能作用于CSS的 url()
导入方式:
$family: unquote("Droid_sans");
@import url("http://fonts.googleapis.com/css?family=\#{$family}");
编译为
@import url("http://fonts.googleapis.com/css?family=Droid+Sans");
7.1.1. 分音 (Partials)
不希望编译为 CSS文件,只需要在文件名前添加下划线,@import一个局部文件时,导入语句中可以省略下划线,注意不要重名。
7.1.2. 嵌套 @import
sass允许@import
命令写在css
规则内,生成对应的css文件时,也可以将 @import 嵌套进 CSS 样式或者 @media 中,只是这样导入的样式只能出现在嵌套的层中。
不可以在混合指令 (mixin
) 或控制指令 (control directives
) 中嵌套 @import
。
不能用sass的@import直接导入一个原始的css文件
7.2. @media
Sass 中 @media
指令与 CSS 中用法一样,只是允许其在 CSS 规则中嵌套,编译时,@media
将被编译到文件的最外层,包含嵌套的父选择器。
@media
的 queries 允许互相嵌套使用,编译时,Sass 自动添加 and
:
@media screen {
.sidebar {
@media (orientation: landscape) {
width: 500px;
}
}
}
编译为
@media screen and (orientation: landscape) {
.sidebar {
width: 500px; } }
@media 甚至可以使用 SassScript(比如变量,函数,以及运算符)代替条件的名称或者值:
$media: screen;
$feature: -webkit-min-device-pixel-ratio;
$value: 1.5;
@media #{$media} and ($feature: $value) {
.sidebar {
width: 500px;
}
}
7.3. @extend
一个选择器下的所有样式继承给另一个选择器,通过@extend
语法实现:
//通过选择器继承继承样式
.error {
border: 1px solid red;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
其他使用到 .error 的样式也会同样继承给 .seriousError。
7.3.1. How it Works
当合并选择器时,@extend 会很聪明地避免无谓的重复,不能匹配任何元素的选择器也会删除。
7.3.2. 延伸复杂的选择器 (Extending Complex Selectors)
Class 选择器并不是唯一可以被延伸 (extend) 的,Sass 允许延伸任何定义给单个元素的选择器,比如 .special.cool
,a:hover
或者 a.user[href^="http://"]
等,
7.3.3. 多重延伸 (Multiple Extends)
同一个选择器可以延伸给多个选择器,它所包含的属性将继承给所有被延伸的选择器:
.seriousError {
@extend .error;
@extend .attention;
border-width: 3px;
}
多重延伸可以使用逗号分隔选择器名,@extend .error, .attention;
7.3.4. 继续延伸 (Chaining Extends)
当一个选择器延伸给第二个后,可以继续将第二个选择器延伸给第三个:
.seriousError {
@extend .error;
border-width: 3px;
}
.criticalError {
@extend .seriousError;
position: fixed;
}
7.3.5. 选择器列 (Selector Sequences)
暂时不可以将选择器列 (Selector Sequences),比如 .foo .bar
或 .foo + .bar
,延伸给其他元素,但是,却可以将其他元素延伸给选择器列:
#fake-links .link {
@extend a;
}
7.3.5.1. 合并选择器列 (Merging Selector Sequences)
有时会遇到复杂的情况,比如选择器列中的某个元素需要延伸给另一个选择器列,这种情况下,两个选择器列需要合并,比如:
#admin .tabbar a {
font-weight: bold;
}
#demo .overview .fakelink {
@extend a;
}
技术上讲能够生成所有匹配条件的结果,但是这样生成的样式表太复杂了,所以,Sass 只会编译输出有用的选择器。
当两个列 (sequence) 合并时,如果没有包含相同的选择器,将生成两个新选择器:第一列出现在第二列之前,或者第二列出现在第一列之前:
如果两个列 (sequence) 包含了相同的选择器,相同部分将会合并在一起,其他部分交替输出。
7.3.6. @extend-Only 选择器 (@extend-Only Selectors)
当一套样式只通过 @extend
指令使用时,希望不被编译到 CSS 文件中,使用占位符选择器%
来编写:
.notice {
@extend %extreme;
}
7.3.7. !optional
声明 (The !optional Flag)
@extend 失败会收到错误提示,可以通过 !optional
声明解决
a.important {
@extend .notice !optional;
}
7.3.8. 在指令中延伸 (@extend in Directives)
Sass 不可以将 @media
层外的 CSS 规则延伸给指令层内的 CSS,这样会生成大量的无用代码。
7.4. @at-root
跳出嵌套
.parent {
...
@at-root .child { ... }
}
或者
@at-root {
.child1 { ... }
.child2 { ... }
}
7.4.1. @at-root (without: …) and @at-root (with: …)
默认情况下,@at root
只排除选择器。但是,也可以用于跳出嵌套指令,如@media
;
使用@at-root(without:...)
跳出任何指令,使用空格添加多个作用指令:@at-root(without: media supports)
@media print {
.page {
width: 8in;
@at-root (without: media) {
color: red;
}
}
}
编译出
@media print {
.page {
width: 8in;
}
}
.page {
color: red;
}
有两个特殊值可以传递给@at root:
@at-root (without: rule)
与@at-root不带查询一样;
@at-root (without: all)
样式移动到所有指令和css规则之外。
如果要指定要包含哪些指令或规则,而不是跳出,应该用@at-root(with:...)
7.5. @debug
@debug
指令将sasscript表达式的值打印到标准错误输出流。用于调试正在进行复杂sassscript的sass文件。例如:
@debug 10em + 12em;
编译为
Line1 DEBUG: 22em
7.6. @warn
@warn
指令将sasscript表达式的值打印到标准错误输出流。对于那些需要警告用户拒绝使用或从轻微的mixin使用错误中恢复的库非常有用。
@warn
和@debug
两个主要区别:
- 可以使用
--quiet
命令选项或quiet Sass option
关闭警告 - 样式表跟踪将与消息一起打印出来,这样就可以看到样式在哪里引起了警告。
@mixin adjust-location($x, $y) {
@if unitless($x) {
@warn "Assuming #{$x} to be in pixels";
$x: 1px * $x;
}
@if unitless($y) {
@warn "Assuming #{$y} to be in pixels";
$y: 1px * $y;
}
position: relative; left: $x; top: $y;
}
7.7. @error
@error指令将sasscript表达式的值作为致命错误抛出,包括一个很好的的堆栈跟踪。它对于验证混合函数和函数的参数很有用。例如:
@mixin adjust-location($x, $y) {
@if unitless($x) {
@error "$x may not be unitless, was #{$x}.";
}
@if unitless($y) {
@error "$y may not be unitless, was #{$y}.";
}
position: relative; left: $x; top: $y;
}
8. 控制指令 (Control Directives)
主要与混合指令 (mixin
) 配合使用,尤其是用在 Compass 等样式库中。
8.1. if()
可以在任何脚本上下文中使用。if函数只计算与它将返回的参数相对应的参数,这允许您引用可能未定义的变量,或者进行计算,否则会导致错误(例如除以零)。
8.2. @if
当 @if
的表达式返回值不是 false
或者 null
时,条件成立,输出 {}
内的代码:
p {
@if 1 + 1 == 2 { border: 1px solid; }
@if 5 < 3 { border: 2px dotted; }
@if null { border: 3px double; }
}
@if
声明后面可以跟多个 @else if
声明,或者一个 @else
声明。
8.3. @for
@for
指令可以在限制范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动。
包括两种格式:
@for $var from <start> through <end>
@for $var from <start> to <end>
当使用 through
时,条件范围包含 <start>
与 <end>
的值,而使用 to
条件时范围只包含 <start
的值不包含 <end>
的值。<start>
和<end>
必须是整数值。
@for $i from 1 trough 3 {
.item-#{$i} { width: 2em * $i;}
}
编译为
.item-1 {
width: 2em; }
.item-2 {
width: 4em; }
.item-3 {
width: 6em; }
8.4. @each
@each
格式的指令是 $var in <list>
,list
是值列表。@each
将变量 $var
作用于值列表的每一个项目,然后输出结果,
@each $animal in puma, sea-slug, egret, salamandar {
.#{$animal}-icoon {
background-image: url("/images/#{$animal}.png");
}
}
编译为
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'); }
8.4.1 多重变量 (Multiple Assignment)
@each
指令还可以使用多个变量,如@each$var1,$var2,… in
。如果是列表项,则将子列表的每个元素分配给各自的变量。例如:
@each $animal, $color $cursor in (puma, black, default),
(sea-slug, blue, pointer),
(egret, white, move) {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
border: 2px solid $color;
cursor: $cursor;
}
}
编译为
.puma-icon {
background-image: url('/images/puma.png');
border: 2px solid black;
cursor: default; }
.sea-slug-icon {
background-image: url('/images/sea-slug.png');
border: 2px solid blue;
cursor: pointer; }
.egret-icon {
background-image: url('/images/egret.png');
border: 2px solid white;
cursor: move; }
键值对的形式也是可以:
@each #header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
#{header} {
font-size: $size;
}
8.5. @while
@while
指令重复输出格式知道表达式返回结果为 false
,可以实现比 @for 更复杂的循环,例如:
$i: 6;
@while $i > 0 {
.item-#{$i} {
width: 2em * $i;
}
$i: $i - 2;
}
编译为
.item-6 {
width: 12em; }
.item-4 {
width: 8em; }
.item-2 {
width: 4em; }
9. 混合指令 (Mixin Directives)
混合指令(Mixin)用于定义可重复使用的样式,避免了无语意的class,
9.1. 定义混合指令 @mixin (Defining a Mixin: @mixin)
用法是在 @mixin 后添加名称与样式:
@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
}
不仅可以包含选择器和属性,甚至可以用 & 引用父选择器:
@mixin clearfix {
display: inline-block;
&:after {
content: ".";
display: block;
clear: both;
}
* html & { height: 1px }
}
9.2. 引用混合样式 @include (Including a Mixin: @include)
使用 @include 指令引用混合样式:
.page-title {
@include large-text;
padding: 4px;
margin-top: 10px;
}
混合样式中也可以包含其他混合样式,比如:
@mixin compound {
@include highlighted-background;
@include header-text;
}
@mixin highlighted-background { background-color: #fc0; }
@mixin header-text { font-size: 20px; }
9.3. 参数 (Arguments)
按照变量的格式,通过逗号分隔,将参数写进圆括号里。引用指令时,按照参数的顺序,再将所赋的值对应写进括号:
@mixin sexy-border($color, $width) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
p { @include sexy-border(blue, 1in); }
sass允许通过语法$name: value
的形式指定每个参数的值。参数顺序就不必再在乎了,只需要保证没有漏掉参数即可:
a {
@include link-colors(
$normal: blue,
$visited: green,
$hover: red
);
}
默认参数值
为了在@include混合器时不必传入所有的参数,我们可以给参数指定一个默认值:
@mixin sexy-border($color, $width: 1in) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
p { @include sexy-border(blue); }
h1 { @include sexy-border(blue, 2in); }
9.3.1. 关键词参数 (Keyword Arguments)
混合指令也可以使用关键词参数(键值对形式),上面的例子也可以写成:
p { @include sexy-border($color: blue); }
h1 { @include sexy-border($color: blue, $width: 2in); }
9.3.2. 参数变量 (Variable Arguments)
有时,不能确定混合指令需要使用多少个参数,可以使用参数变量 …
声明(写在参数的最后方):
@mixin box-shadow($shadows...) {
-moz-box-shadow: $shadows;
-webkit-box-shadow: $shadows;
box-shadow: $shadows;
.shadows {
@include box-shadow(0 4px 5px #666, 2px 6px 10px #999);
参数变量也可以用在引用混合指令的时候 (@include
),与平时用法一样,将一串值列表中的值逐条作为参数引用:
@mixin colors($text, $background, $border) {
color: $text;
background-color: $background;
border-color: $border;
}
$values: #ff0000, #00ff00, #0000ff;
.primary {
@include colors($values...);
}
可以使用变量参数包装mixin并添加其他样式:
@mixin wrapped-stylish-mixin($args...) {
font-weight: bold;
@include stylish-mixin($args...);
}
.stylish {
// $width 参数将会传递给 stylish-mixin 作为关键词
@include wrapped-stylish-mixin(#00ff00, $width: 100px);
}
9.4. 向混合样式中导入内容 (Passing Content Blocks to a Mixin)
在引用混合样式的时候,可以先将一段代码导入到混合指令中,然后再输出混合样式,额外导入的部分将出现在 @content
标志的地方:
@mixin apply-to-ie6-only {
* html {
@content;
}
}
@include apply-to-ie6-only {
#logo {
background-image: url(/logo.gif);
}
}
编译为
* html #logo {
background-image: url(/logo.gif);
}
为便于书写,@mixin
可以用 =
表示,而 @include 可以用 +
表示,所以上面的例子可以写成:
=apply-to-ie6-only
* html
@content
+apply-to-ie6-only
#logo
background-image: url(/logo.gif)
当 @content
在指令中出现过多次或者出现在循环中时,额外的代码将被导入到每一个地方。
9.4.1. Variable Scope and Content Blocks
mixin的局部变量不能在传递的样式块中使用,并且变量将解析为全局值:
$color: white;
@mixin colors($color: blue) {
background-color: $color;
@content;
border-color: $color;
}
.colors {
@include colors { color: $color; }
}
编译为
.colors {
background-color: blue;
color: white;
border-color: blue;
}
10. 函数指令 (Function Directives)
Sass 支持自定义函数,并能在任何属性值或 Sass script 中使用,需要调用 @return
输出结果:
$grid-width: 40px;
$gutter-width: 10px;
@function grid-width($n) {
@return $n * $grid-width + ($n - 1) * $gutter-width;
}
#sidebar { width: grid-width(5); }
11. 输出格式 (Output Style)
Sass 提供了四种输出格式,可以通过 :style option
选项设定,或者在命令行中使用 --style
选项。
11.1. :nested
Nested (嵌套)样式是 Sass 默认的输出格式,选择器与属性等单独占用一行,缩进量与 Sass 文件中一致,每行的缩进量反映了其在嵌套规则内的层数。
11.2. :expanded
扩展型:”Expanded 输出更像是手写的样式,选择器、属性等各占用一行,属性根据选择器缩进,而选择器不做任何缩进。
11.3. :compact
紧凑型:每条 CSS 规则只占一行,包含其下的所有属性。
嵌套过的选择器在输出时没有空行,不嵌套的选择器会输出空白行作为分隔符。
11.4. :compressed
压缩型:删除所有无意义的空格、空白行、以及注释,力求将文件体积压缩到最小,同时也会做出其他调整,比如会自动替换占用空间最小的颜色表达方式。
12. 拓展 Sass (Extending Sass)
使用这些功能需要有良好的 Ruby 基础。