为什么使用 Sass
原理
变量
使用 $ 标识变量。
将反复使用的 css 属性值定义为变量,从而无需重复书写该属性值。一个通俗易懂的变量名也可以让人一眼就明白该属性值的用途。
声明变量
- 用冒号:而不是=
- 可以单个;多个可用空格或者逗号隔开。
- 定义在规则块内时就只有块内能使用。
- 中划线 - 、下划线 _ 都可以,兼容——意味着 不区分这两个:
$link-color
和$link_color
其实指向的是同一个变量;纯css处不互通。如类名、ID、属性名
变量引用
- 带着 $ 使用
-
嵌套
嵌套规则
css 有时要重复写选择器,非常麻烦。
#content article h1 { color: #333 }
#content article p { margin-bottom: 1.4em }
#content aside { background-color: #EEE }
Sass 可以只写一遍—即将所有的嵌套在一个大的选择其中,可读性也变得更高。
#content {
article {
h1 { color: #333 }
p { margin-bottom: 1.4em }
}
aside { background-color: #EEE }
}
/* 编译后 */
#content article h1 { color: #333 }
#content article p { margin-bottom: 1.4em }
#content aside { background-color: #EEE }
但是嵌套的选择器中无法使用 类似:hover的伪类。这与 Sass 的编译有关
父选择器的标识符 &
在使用类似 : hover 这样的伪类时,在前面加上 &,即这个玩意 就代表父 ```css article a { color: blue; &:hover { color: red }/ 即这里 & 就是 article/ }
//编译后 article a { color: blue } article a:hover { color: red }
在父选择器之前添加选择器<br />如判断当用户在使用IE浏览器时,你会通过JavaScript在<body>标签上添加一个ie的类名,为这种情况编写特殊的样式如下:
```css
#content aside {
color: red;
body.ie & { color: green }
}
/*编译后*/
#content aside {color: red};
body.ie #content aside { color: green }
群组选择器的嵌套
如果你需要在一个特定的容器元素内对这样一个群组选择器进行修饰,情况就不同了。css的写法会让你在群组选择器中的每一个选择器前都重复一遍容器元素的选择器。
.container {
h1, h2, h3 {margin-bottom: .8em}
}
nav, aside {
a {color: blue}
}
/*编译后*/
.container h1, .container h2, .container h3 { margin-bottom: .8em }
nav a, aside a {color: blue}
子组合与同层选择器 > + ~
>
子层
- 中间什么都没有,就是选择 article 下的所有 section
- > : 选择器只会选择article下紧跟着的子元素中命中section选择器的元素。
article section { margin: 5px }
article > section { border: 1px solid #ccc }
+
用同层相邻组合选择器+选择元素后紧跟的兄弟元素
选择header元素后紧跟的p元素header + p { font-size: 1.1em }
~
后面的全部
选择所有跟在article后的同层article元素,不管它们之间隔了多少其他元素article ~ article { border-top: 1px dashed #ccc }
这些东西也都能嵌套
article {
~ article { border-top: 1px dashed #ccc }
> footer { background: #eee }
dl > {
dt { color: #333 }
dd { color: #555 }
}
nav + & { margin-top: 0 }
}
//解开
article ~ article { border-top: 1px dashed #ccc }
article > footer { background: #eee }
article dl > dt { color: #333 }
article dl > dd { color: #555 }
nav + article { 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;
}
}
//===
nav {
border: 1px solid #ccc;
border-left: 0px;
border-right: 0px;
}
导入Sass文件
css有一个特别不常用的特性,即@import规则,它允许在一个css文件中导入其他css文件。然而,后果是只有执行到@import时,浏览器才会去下载其他css文件,这导致页面加载起来特别慢。 sass也有一个@import规则,但不同的是,sass的@import规则在生成css文件时就把相关文件导入进来。这意味着所有相关的样式被归纳到了同一个css文件中,而无需发起额外的下载请求。另外,所有在被导入文件中定义的变量和混合器均可在导入文件中使用。 使用sass的@import规则并不需要指明被导入文件的全名。你可以省略.sass或.scss文件后缀
局部文件
此约定即,sass局部文件的文件名以下划线开头。这样,sass就不会在编译时单独编译这个文件输出css,而只把这个文件用作导入。但引入时可以省略开头的下划线。
默认变量
反复声明一个变量时,最后一次会覆盖掉前面全部的,也就是说只有最后一个生效。如果你想你写出的 Sass 文件被别人引入后可以定制修改某些值:使用sass的!default
标签可以实现这个目的。它很像css属性中!important
标签的对立面,不同的是!default
用于变量,含义是:如果这个变量被声明赋值了,那就用它声明的值,否则就用这个默认值。哪怕导入者定义的变量在引入文件之前,变量仍不会给覆盖。
嵌套导入
sass允许@import命令写在css规则内。也就是 直接引入了 被引入文件的所有代码片段 放进引入的地方。
原生CSS导入
你不能用sass的@import直接导入一个原始的css文件,因为sass会认为你想用css原生的@import。但是,因为sass的语法完全兼容css,所以你可以把原始的css文件改名为.scss后缀,即可直接导入了
静默注释
Sass 有两种注释方法
CSS 自带的 /*...*/
注释,如果生成的 CSS 文件中,该处允许注释,那么就存在,否则(如在css属性或选择器中)会被抹去。
Sass 新提供的 //
注释 ,生成的 CSS 文件中会被抹去。
混合器
有时需要大段的重复代码,就需要使用混合器,定义标识符:@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;
}
//编译后:
.notice {
background-color: green;
border: 2px solid #00aa00;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
使用混合器把你样式中的通用样式抽离出来,然后轻松地在其他地方重用,但大量的重用可能会导致生成的样式表过大,导致加载缓慢。
何时使用混合器
判断一组属性是否应该组合成一个混合器,一条经验法则就是你能否为这个混合器想出一个好的名字。如果你能找到一个很好的短名字来描述这些属性修饰的样式,比如rounded-cornersfancy-font
或者no-bullets
,那么往往能够构造一个合适的混合器。如果你找不到,这时候构造一个混合器可能并不合适。
与类名关系
类名是在html文件中应用的,而混合器是在样式表中应用的。这就意味着类名具有语义化含义,而不仅仅是一种展示性的描述:用来描述html元素的含义而不是html元素的外观。而另一方面,混合器是展示性的描述,用来描述一条css规则应用之后会产生怎样的效果。
混合器中的CSS规则
混合器传参
像函数一样,定义时后面 ( ) 里传变量参数,调用时传入 实参。当你@include混合器时,有时候可能会很难区分每个参数是什么意思,参数之间是一个什么样的顺序。为了解决这个问题,sass允许通过语法**$name: value**
的形式指定每个参数的值。这种形式的传参,参数顺序就不必再在乎了,只需要保证没有漏掉参数即可。
默认参数值
也是和函数一样在括号里就先赋上一个值,如果没传入新的值,就用这个默认的。
选择器继承
**@expand**
来实现继承一个 另一个选择器。
//通过选择器继承继承样式
.error {
border: 1px solid red;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
何时使用继承器
继承是基于类的,所以继承也是基于语义化的关系上,当一个类属于另一个类自然也就是继承。
继承的高级用法
- 假如一条样式规则继承了一个复杂的选择器,那么它只会继承这个复杂选择器命中的元素所应用的样式。举例来说, 如果.seriousError
@extend.**important**.**error**
, 那么.important.error 和h1.important.error 的样式都会被.seriousError继承, 但是.important或者.error下的样式则不会被继承。也就是不会分别继承如果一个选择器序列(#main .seriousError)@extend另一个选择器(.error),那么只有完全匹配#main .seriousError这个选择器的元素才会继承.error的样式,就像单个类 名继承那样。拥有class=”seriousError”的#main元素之外的元素不会受到影响。
像#main .error这种选择器序列是不能被继承的。这是因为从#main .error中继承的样式一般情况下会跟直接从.error中继承的样式基本一致,细微的区别往往使人迷惑。
继承的工作细节
@extend背后最基本的想法是,如果.seriousError @extend .error, 那么样式表中的任何一处.error都用.error.seriousError这一选择器组进行替换。
关于@extend有两个要点你应该知道。
- 跟混合器相比,继承生成的css代码相对更少。因为继承仅仅是重复选择器,而不会重复属性,所以使用继承往往比混合器生成的css体积更小。如果你非常关心你站点的速度,请牢记这一点。
- 继承遵从css层叠的规则。当两个不同的css规则应用到同一个html元素上时,并且这两个不同的css规则对同一属性的修饰存在不同的值,css层叠规则会决定应用哪个样式。相当直观:通常权重更高的选择器胜出,如果权重相同,定义在后边的规则胜出。
混合器本身不会引起css层叠的问题,因为混合器把样式直接放到了css规则中.
继承的最佳实践
继承只会在生成css时复制选择器,而不会复制大段的css属性。但是如果你不小心,可能会让生成的css中包含大量的选择器复制。避免的方法:别在后代选择器中去继承别人。
总结
想了解更多请看文档,本文简单入门,也可以用于回头检查自己。