Sass变量、嵌套
声明变量
定义变量的语法
Sass 的变量包括三个部分:
声明变量的符号“$”
变量名称
赋予变量的值
简单的示例,假设你的按钮颜色可以给其声明几个变量:
1 $brand-primary : darken(#428bca, 6.5%) !default;/* #337ab7*/
2 $btn-primary-color : #fff !default;
3 $btn-primary-bg : $brand-primary !default;
4 $btn-primary-border : darken($btn-primary-bg, 5%) !default;
5 /*如果值后面加上!default则表示默认值。*/
普通变量与默认变量
普通变量
定义之后可以在全局范围内使用
1 $fontSize: 12px;
2 body{
3 font-size:$fontSize;
4 }
编译后的CSS代码:
1 body{
2 font-size:12px;
3 }
默认变量
sass的默认变量仅需要在值的后面加上!default即可。
1 $baseLineHeight:1.5 !default;
2 body{
3 line-height: $baseLineHeight;
4 }
编译后的css代码:
1 body{
2 line-height:1.5;
3 }
sass 的默认变量一般是用来设置默认值,然后根据需求来覆盖的,覆盖的方式也很简单,只需要在默认变量之前重新声明下变量即可。
1 $baseLineHeight: 2;
2 $baseLineHeight: 1.5 !default;
3 body{
4 line-height: $baseLineHeight;
5 }
编译后的css代码:
1 body{
2 line-height:2;
3 }
可以看出现在编译后的 line-height 为 2,而不是我们默认的 1.5。默认变量的价值在进行组件化开发的时候会非常有用。
局部变量和全局变量
如果已经存在同名的全局变量,从 3.4 版本开始,Sass 已经可以正确处理作用域的概念,并通过创建一个新的局部变量来代替。
全局变量与局部变量
1 /*SCSS*/
2 $color: orange !default;/*定义全局变量(在选择器、函数、混合宏...的外面定义的变量为全局变量)*/
3 .block {
4 color: $color;//调用全局变量
5 }
6 em {
7 $color: red;//定义局部变量
8 a {
9 color: $color;//调用局部变量
10 }
11 }
12 span {
13 color: $color;//调用全局变量
14 }
css 的结果:
1 /*CSS*/
2 .block {
3 color: orange;
4 }
5 em a {
6 color: red;
7 }
8 span {
9 color: orange;
10 }
在元素内部定义的变量不会影响其他元素。如此可以简单的理解成,全局变量就是定义在元素外面的变量,如下代码:
$color:orange !default;
$color 就是一个全局变量,而定义在元素内部的变量,比如 $color:red; 是一个局部变量。
全局变量的影子
当在局部范围(选择器内、函数内、混合宏内...)声明一个已经存在于全局范围内的变量时,局部变量就成为了全局变量的影子。基本上,局部变量只会在局部范围内覆盖全局变量。
上面例子中的 em 选择器内的变量 $color 就是一个全局变量的影子。
1 /*SCSS*/
2 $color: orange !default;//定义全局变量
3 .block {
4 color: $color;//调用全局变量
5 }
6 em {
7 $color: red;//定义局部变量(全局变量 $color 的影子)
8 a {
9 color: $color;//调用局部变量
10 }
11 }
什么时候声明变量?
建议:创建变量只适用于感觉确有必要的情况下。不要为了某些骇客行为而声明新变量,这丝毫没有作用。只有满足所有下述标准时方可创建新变量:
1、该值至少重复出现了两次;
2、该值至少可能会被更新一次;
3、该值所有的表现都与变量有关(非巧合)。
4、基本上,没有理由声明一个永远不需要更新或者只在单一地方使用变量。
嵌套-选择器嵌套
Sass 中还提供了选择器嵌套功能,但这也并不意味着你在 Sass 中的嵌套是无节制的,因为你嵌套的层级越深,编译出来的 CSS 代码的选择器层级将越深
Sass 的嵌套分为三种:
选择器嵌套
属性嵌套
伪类嵌套
1、选择器嵌套
假设我们有一段这样的结构:
1 <header>
2 <nav>
3 <a href=“##”>Home</a>
4 <a href=“##”>About</a>
5 <a href=“##”>Blog</a>
6 </nav>
7 <header>
想选中 header 中的 a 标签,在写 CSS 会这样写:
1 nav a {
2 color:red;
3 }
4 header nav a {
5 color:green;
6 }
那么在 Sass 中,就可以使用选择器的嵌套来实现:
1 nav {
2 a {
3 color: red;
4
5 header & {
6 color:green;
7 }
8 }
9 }
引用父选择符: &
1 a {
2 font-weight: bold;
3 text-decoration: none;
4 &:hover { text-decoration: underline; }
5 body.firefox & { font-weight: normal; }
6 }
被编译为:
1 a {
2 font-weight: bold;
3 text-decoration: none; }
4 a:hover {
5 text-decoration: underline; }
6 body.firefox a {
7 font-weight: normal; }
&
在编译时将被替换为父选择符,输出到 CSS 中。 也就是说,如果你有一个深层嵌套的规则,父选择符也会在 &
被替换之前被完整的解析
1 #main {
2 color: black;
3 a {
4 font-weight: bold;
5 &:hover { color: red; }
6 }
7 }
被编译为:
1 #main {
2 color: black; }
3 #main a {
4 font-weight: bold; }
5 #main a:hover {
6 color: red; }
嵌套-属性嵌套
Sass中还提供属性嵌套,CSS有一些属性前缀相同,只是后缀不一样,比如:border-top/border-right,与这个类似的还有margin、padding、font等属性。
例:
1 .box{
2 border-top: 1px solid red;
3 border-bottom: 1px solid green;
4 }
在Sass中可以这样写:
1 .box{
2 border:{
3 top: 1px solid red;
4 bottom: 1px solid green;
5 }
6 }
嵌套-伪类嵌套
伪类嵌套和属性嵌套非常类似,只不过他需要借助“&”符号一起配合使用。
就拿经典的“clearfix”为例吧:
1 .clearfix{
2 &:before,&:after {
3 content:"";
4 display: table;
5 }
6 &:after {
7 clear:both;
8 overflow: hidden;
9 }
10 }
编译出来的 CSS:
1 clearfix:before, .clearfix:after {
2 content: "";
3 display: table;
4 }
5 .clearfix:after {
6 clear: both;
7 overflow: hidden;
8 }
避免选择器嵌套:
选择器嵌套最大的问题是将使最终的代码难以阅读。开发者需要花费巨大精力计算不同缩进级别下的选择器具体的表现效果。
选择器越具体则声明语句越冗长,而且对最近选择器的引用(&)也越频繁。在某些时候,出现混淆选择器路径和探索下一级选择器的错误率很高,这非常不值得。
为了防止此类情况,我们应该尽可能避免选择器嵌套。然而,显然只有少数情况适应这一措施。