1. 变量(Variables)
store information that you want to reuse throughout your stylesheet.
①变量声明使用$
当变量定义在css规则块内或其他任何{...}内,那么该变量只能在此规则块内使用
②变量引用
css
生成时,变量会被它们的值所替代;
在声明变量时,变量值也可以引用其他变量;
变量名可以包括中划线和下划线,这两种方式的命名互通(用中划线声明的变量可以使用下划线的方式引用,反之亦然);(也包括对混合器和Sass函数的命名,但纯CSS不互通)
// 变量声明
$highlight-color: #F90;
// 变量引用
border: 1px solid $highlight-color;
// 变量名使用-和_
$link-color: blue;
a {
color: $link_color;
}
2. 嵌套CSS规则(Nesting)
overly nested rules will result in over-qualified CSS,hard to maintain.
①规则块既可以像普通的CSS那样包含属性,又可以嵌套其他规则块
②父选择器的标识符&
编译时&被父选择器直接替换;
可以在父选择器之前添加选择器
// 嵌套
#content {
background-color: #f5f5f5;
article {
h1 { color: #333 }
p { margin-bottom: 1.4em }
}
aside { background-color: #EEE }
}
// 父选择器&
article a {
color: blue;
&:hover { color: red }
}
// 在父选择器之前添加选择器
#content aside {
color: red;
body.ie & { color: green }
}
③群组选择器的嵌套
注意群组选择器的规则嵌套生成的css,
样式表看上去很小,但实际生成的css
却可能非常大,这会降低网站的速度
// 群组选择器
.container {
h1, h2, h3 {margin-bottom: .8em}
}
// 编译后
.container h1,
.container h2,
.container h3
{ margin-bottom: .8em }
④子组合选择器和同层组合选择器:>、+和~
/ 选择一个元素的直接子元素
article > section { border: 1px solid #ccc }
// 选择header元素后紧跟的p元素
header + p { font-size: 1.1em }
// 选择所有跟在article后的同层article元素,不管它们之间隔了多少其他元素
article ~ article { border-top: 1px dashed #ccc }
// 在SASS中使用
article {
~ article { border-top: 1px dashed #ccc }
> section { background: #eee }
dl > {
dt { color: #333 }
dd { color: #555 }
}
nav + & { margin-top: 0 }
}
⑤嵌套属性
// 属性嵌套
nav {
border: {
style: solid;
width: 1px;
color: #ccc;
}
}
// 编译后
nav {
border-style: solid;
border-width: 1px;
border-color: #ccc;
}
// 声明例外情况
nav {
border: 1px solid #ccc {
left: 0px;
right: 0px;
}
}
3. 导入SASS文件
css 的@import规则,只有执行到@import
时,浏览器才会去下载其他css
文件,导致页面加载起来特别慢;
sass
的@import
规则在生成css
文件时就把相关文件导入进来,所有相关的样式被归纳到了同一个css
文件中,无需发起额外的下载请求。另外,所有在被导入文件中定义的变量和混合器均可在导入文件中使用。
不需要指明被导入文件的全名,可以省略.sass
或.scss
文件后缀。
①使用SASS部分文件(Partials)
那些专门为@import
命令而编写的sass
文件,并不需要生成对应的独立css
文件,这样的sass
文件称为局部文件。局部文件的文件名以下划线开头,这样sass
就不会在编译时单独编译这个文件输出css
,而只把这个文件用作导入。@import
一个局部文件时,可以省略文件名开头的下划线。
// 导入themes/_night-sky.scss文件中的内容
@import "themes/night-sky";
②默认变量值 !default
$fancybox-width: 400px !default;
.fancybox {
width: $fancybox-width;
}
// 如果用户在导入你的sass局部文件之前声明了一个$fancybox-width变量,那么你的局部文件中对$fancybox-width赋值400px的操作就无效。如果用户没有做这样的声明,则$fancybox-width将默认为400px
③嵌套导入
sass
允许@import
命令写在css
规则内,生成对应的css
文件时,局部文件会被直接插入到css
规则内导入它的地方
被导入的局部文件中定义的所有变量和混合器,不会全局有效,只会在这个规则范围内生效。
// 局部文件 _blue-theme.scss
aside {
background: blue;
color: white;
}
// 导入
.blue-theme {@import "blue-theme"}
// 编译后
.blue-theme {
aside {
background: blue;
color: #fff;
}
}
④原生的CSS导入
通常在sass
中使用@import
时,sass
会尝试找到对应的sass
文件并导入进来,但在下列三种情况下会生成原生的CSS@import
,尽管这会造成浏览器解析css
时的额外下载:
- 被导入文件的名字以
.css
结尾; - 被导入文件的名字是一个URL地址(比如http://www.sass.hk/css/css.css),由此可用谷歌字体API提供的相应服务;
- 被导入文件的名字是
CSS
的url()值。
不能用sass
的@import
直接导入一个原始的css
文件,因为sass
会认为你想用css
原生的@import
。但是,因为sass
的语法完全兼容css
,可以把原始的css
文件改名为.scss
后缀,即可直接导入了
4. 静默注释
静默注释的内容不会出现在生成的css
文件中;
以//
开头,注释内容直到行末。
body {
color: #333; // 这种注释内容不会出现在生成的css文件中
padding: 0; /* 这种注释内容会出现在生成的css文件中 */
}
当注释出现在原生css
不允许的地方,如在css
属性或选择器中,sass
将不知如何将其生成到对应css
文件中的相应位置,这些注释会被抹掉
body {
color /* 这块注释内容不会出现在生成的css中 */: #333;
padding: 1; /* 这块注释内容也不会出现在生成的css中 */ 0;
}
5. 混合器(Mixins)@mixin
实现大段样式的重用。
大量的使用混合器可能会导致生成的样式表过大,导致加载缓慢,因此要避免滥用。
① @mixin标识符给一大段样式赋予一个名字,可以通过引用这个名字重用这段样式
② 通过@include
来使用这个混合器
// 声明
@mixin rounded-corners {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
// 使用
notice {
background-color: green;
border: 2px solid #00aa00;
@include rounded-corners;
}
③ 何时使用混合器
如果你发现自己在不停地重复一段样式,那就应该把这段样式构造成优良的混合器,尤其是这段样式本身就是一个逻辑单元,比如说是一组放在一起有意义的属性
混合器在某些方面跟css
类名很像,类名具有语义化含义,而不仅仅是一种展示性的描述:它用来描述html
元素的含义而不是html
元素的外观。混合器是展示性的描述,用来描述一条css
规则应用之后会产生怎样的效果
notice {
background-color: green;
border: 2px solid #00aa00;
@include rounded-corners;
}
④混合器中的CSS规则
混合器中不仅可以包含属性,也可以包含css
规则,包含选择器和选择器中的属性;
混合器中的规则甚至可以使用sass
的父选择器标识符&
。使用起来跟不用混合器时一样;
@mixin no-bullets {
list-style: none;
li {
list-style-image: none;
list-style-type: none;
margin-left: 0px;
}
}
// 引用
ul.plain {
color: #444;
@include no-bullets;
}
// 编译后
ul.plain {
color: #444;
list-style: none;
}
ul.plain li {
list-style-image: none;
list-style-type: none;
margin-left: 0px;
}
⑤ 给混合器传参
可以通过在@include
混合器时给混合器传参,来定制混合器生成的精确样式;
参数就是可以赋值给css
属性值的变量;
@mixin link-colors($normal, $hover, $visited) {
color: $normal;
&:hover { color: $hover; }
&:visited { color: $visited; }
}
// 引用
a {
@include link-colors(blue, red, green);
}
//编译后
a { color: blue; }
a:hover { color: red; }
a:visited { color: green; }
sass
允许通过语法$name: value
的形式指定每个参数的值。这种形式的传参,不必再在乎参数顺序,只需保证没有漏掉参数即可
a {
@include link-colors(
$normal: blue,
$visited: green,
$hover: red
);
}
⑥ 默认参数值 $name: default-value
默认值可以是任何有效的css
属性值,甚至是其他参数的引用
@mixin link-colors(
$normal,
$hover: $normal,
$visited: $normal
)
{
color: $normal;
&:hover { color: $hover; }
&:visited { color: $visited; }
}
// 如果像下边这样调用:@include link-colors(red) $hover和$visited也会被自动赋值为red
6. 使用选择器继承来精简CSS
选择器继承是说一个选择器可以继承为另一个选择器定义的所有样式,通过@extend
语法实现
.error {
border: 1px solid red;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
在上边的代码中,.seriousError
将会继承样式表中任何位置处为.error
定义的所有样式。以class="seriousError"
修饰的html
元素最终的展示效果就好像是class="seriousError error";
.seriousError
不仅会继承.error
自身的所有样式,任何跟.error
有关的组合选择器样式也会被.seriousError
以组合选择器的形式继承;
//.seriousError从.error继承样式
.error a{ //应用到.seriousError a
color: red;
font-weight: 100;
}
h1.error { //应用到hl.seriousError
font-size: 1.2rem;
}
① 何时使用继承
继承应该是建立在语义化的关系上,当一个元素拥有的类(比如说.seriousError
)表明它属于另一个类(比如说.error
),这时使用继承再合适不过了
② 继承的高级用法
继承一个html
元素的样式
.disabled {
color: gray;
@extend a;
}
③ 继承的工作细节
- 跟混合器相比,继承生成的
css
代码相对更少。因为继承仅仅是重复选择器,而不会重复属性,所以使用继承往往比混合器生成的css
体积更小。如果你非常关心你站点的速度,请牢记这一点。 - 继承遵从
css
层叠的规则。当两个不同的css
规则应用到同一个html
元素上时,并且这两个不同的css
规则对同一属性的修饰存在不同的值,css
层叠规则会决定应用哪个样式。相当直观:通常权重更高的选择器胜出,如果权重相同,定义在后边的规则胜出。
④ 使用继承的最佳实践
不要在css
规则中使用后代选择器(比如.foo .bar
)去继承css
规则。如果你这么做,同时被继承的css
规则有通过后代选择器修饰的样式,生成css
中的选择器的数量很快就会失控
.foo .bar { @extend .baz; }
.bip .baz { a: b; }
在上边的例子中,sass
必须保证应用到.baz的样式同时也要应用到.foo .bar
(位于class="foo"的元素内的class="bar"的元素)。例子中有一条应用到.bip .baz
(位于class="bip"的元素内的class="baz"的元素)的css
规则。当这条规则应用到.foo .bar
时,可能存在三种情况:
<!-- Case 1 -->
<div class="foo">
<div class="bip">
<div class="bar">...</div>
</div>
</div>
<!-- Case 2 -->
<div class="bip">
<div class="foo">
<div class="bar">...</div>
</div>
</div>
<!-- Case 3 -->
<div class="foo bip">
<div class="bar">...</div>
</div>
为了应付这些情况,sass
必须生成三种选择器组合(仅仅是.bip .foo .bar不能覆盖所有情况)。如果任何一条规则里边的后代选择器再长一点,sass
需要考虑的情况就会更多