SASS入门2

2015年10月20日

1.嵌套

Sass 中还提供了选择器嵌套功能,但这也并不意味着你在 Sass 中的嵌套是无节制的,因为你嵌套的层级越深,编译出来的 CSS 代码的选择器层级将越深,这往往是大家不愿意看到的一点。这个特性现在正被众多开发者滥用。

Sass的嵌套分为3种:
a.选择器嵌套
b.属性嵌套
c.伪类嵌套

1、选择器嵌套

假设我们有一段这样的结构:

<header>
  <nav>
    <a href=“##”>Home</a>
    <a href=“##”>About</a>
    <a href=“##”>Blog</a>
  </nav>
<header>

想选中header中的a标签,在写CSS会这样写:

nav a {
  color:red;
}

header nav a {
  color:green;
}

那么在Sass中,就可以使用选择器的嵌套来实现:

nav {
  a {
    color: red;

    header & {
      color:green;
    }
  }  
}

2.属性嵌套
Sass中还提供属性嵌套,CSS有一些属性前缀相同,只是后缀不一样,比如:border-top/border-right,与这个类似的还有margin、padding、font等属性。假设你的样式中用到了:

.box{
        border-top: 1px solid red;
        border-bottom: 1px soid green;
}

在Sass中可以这样写:

.box{
       border:{
                  top: 1px solid red;
                  bottom: 1px solid green;
        }
}

3.伪类嵌套
其实伪类嵌套和属性嵌套非常相似,只不过他需要借助'&'符号一起配合使用。我们就拿经典的"clearfix"为例吧:

.clearfix{
              &: bofore,
              &:after{
                          content:"";
                          display: table;
                  }
              &:after{
                          clear: both;
                          overflow: hidden;
                  }
}

编译出来的CSS:

.clearfix:before, .clearfix:after{
    content: "";
    display: table;
}
.clearfix:after{
          clear:both;
          overflow: hidden;
}

尽量避免选择器选择器嵌套

混合宏

如果你的整个网站中有几处小样式类似,比如颜色,字体等,在Sass可以使用变量来统一处理,那么这种选择还是不错的。但当你的样式变得越来越复杂,需要重复使用大段的样式时,使用变量就无法达到我们的目的了。这个时候Sass中的混合宏就会变得非常有意义。

1.声明混合宏
不带参数的混合宏:
在Sass中,使用"@mixin"来声明一个混合宏,如:

@mixin border-radius{
    -webkit-border-radius: 5px;
     border-radius: 5px;
}

其中@mixin是用来声明混合宏的关键词,有点类似CSS中的@media、@font-face一样。border-radius是混合宏的名称。大括号里面是复用的样式代码。

带参数的混合宏:
除了一个不带参数的混合宏之外,还可以在定义混合宏时带有参数,如:

@mixin border-radius($radius:5px){
    -webkit-border-radius: $radius;
    border-radius: $radius;
}

复杂的混合宏:
上面是一个简单的定义混合宏的方法,当然,Sass中的混合宏还提供更为复杂的,你可以在大括号里面写上带有逻辑关系,帮助更好的做你想做的事,如:

@mixin box-shadow($shadow...){
       @if length($shadow) >=1{
               @include prefixer(box-shadow, $shadow);
            } @else{
                     $shadow: 0 0 4px rgba(0, 0, 0, .3);
                      @include prefixer(box-shadow, $shadow);
                  }
}

这个 box-shadow 的混合宏,带有多个参数,这个时候可以使用“ … ”来替代。简单的解释一下,当 $shadow 的参数数量值大于或等于“ 1 ”时,表示有多个阴影值,反之调用默认的参数值“ 0 0 4px rgba(0,0,0,.3) ”。

2.调用混合宏
在Sass中通过@mixin关键词声明了一个混合宏,那么在实际调用中,其匹配了一个关键词"@include"来调用声明好的混合宏。例如在你的样式中定义了一个圆角的混合宏"border-radius":

@mixin border-radius{
         -webkit-border-radius: 3px;
         border-radius: 3px;
}

在一个按钮中要调用定义好的混合宏"border-radius", 可以这样使用:

 button{
      @include border-radius;
}

这个时候编译出来的CSS:

button{
      -webkit-border-radius: 3px;
      border-radius: 3px;
}

3.混合宏的参数
Sass的混合宏有一个强大的功能,可以传参,那么在Sass中传参主要有一下几种情况:
A)传一个不带值的参数
在混合宏中,可以传一个不带任何值的参数,比如:

@mixin border-radius($radius){
      -weblit-border-radius: $radius;
        border-radius: $radius;
}

在混合宏“border-radius”中定义了一个不带任何值的参数“$radius”。

在调用的时候可以给这个混合宏传一个参数值:

.box{
    @include border-radius(3px);
}

这里表示给混合宏传递了一个"border-radius"的值为"3px"。
编译出来的CSS:

.box{
    -webkit-border-radius: 3px;
     border-radius: 3px;
}

B)传一个带值的参数
在Sass的混合宏中,还可以给混合宏的参数传一个默认值,例如:

@mixin border-radius($radius:3px){
      -webkit-border-radius: $radius;
        border-radius: $radius;
}

在混合宏“border-radius”传了一个参数“$radius”,而且给这个参数赋予了一个默认值“3px”。

在调用类似这样的混合宏时,会多有一个机会,假设你的页面中的圆角很多地方都是“3px”的圆角,那么这个时候只需要调用默认的混合宏“border-radius”:

.btn { @include border-radius;}

编译出来的CSS:

.btn{
    -webkit-border-radius: 3px;
      border-radius: 3px;
}

但有的时候,页面中有些元素的圆角值不一样,那么可以随机给混合宏传值,如:

.box { @include border-radius(50%);}

编译出来的CSS:

.box { -webkit-border-radius: 50%; border-radius: 50%;}

C)传多个参数
Sass混合宏除了能传一个参数之外,还可以传多个参数,如:

@mixin center($width, $height){
      width: $width;
      height: $height;
      position: absolute;
      top: 50%;
      left: 50%;
      margin-top: -($height)/2;
      margin-left: -($width)/2;
}

在混合宏"center"就传了多个参数。在实际调用和其调用其他混合宏是一样的:

.box-center{
      @include center(500px, 300px);
}

编译出来的CSS:

.box-center{
      width: 500px;
      height: 300px;
      position: absolute;
      top: 50%;
      left: 50%;
      margin-top: -150px;
      margin-left: -250px;
}

有一个特别的参数"..."。当混合宏传的参数过多之时,可以使用参数来替代,如:

@mixin box-shadow($shadows...){
      @if length($shadows) >= 1{
              -webkit-box-shadow: $shadows;
               box-shadow: $shadows;
          }@else{
                    $shadows: 0 0 2px rgba(#000, .25);
                     -webkit-box-shadow: $shadows;
                      box-shadow: $shadows;
              }
}

在实际调用中:

.box{
      @include box-shadow(0 0 1px rgba(#000, .5), 0 0 2px rgba(#000, .2));
}

编译出来的CSS:
.box{
-webkit-box-shadow: 0 0 1px rgba(0, 0, 0 , 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
box-shadow: 0 0 1px rgba(0, 0, 0 , 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
}

D)混合宏的不足
混合宏在实际编码中给我们带来很多方便之处,特别是对于复用重复代码块。但其最大的不足之处是会生成冗余的代码块。比如在不同的地方调用一个相同的混合宏时。如:

@mixin border-radius{
      -webkit-border-radius: 3px;
          border-radius: 3px;
}
.box{
      @include border-radius;
      margin-bottom: 5px;
}
.btn{
    @include border-radius;
}

示例在".box"和".btn"中都调用了定义好的"border-radius"混合宏。先来看编译出来的CSS:

.box{
      -webkit-border-radius: 3px;
      border-radius: 3px;
      margin-bottom: 5px;
}
.btn{
      -webkit-border-radius: 3px;
         border-radius: 3px;
}

上例明显可以看出,Sass在调用相同的混合宏时,并不能智能的将相同的样式代码块合并在一起。这也是Sass的混合宏最不足之处。

扩展/继承

在Sass中通过关键词"@extend"来继承已存在的类样式块,从而实现代码的继承。如下所示:

//SCSS
.btn{
    border:1px solid #ccc;
    padding: 6px 10px;
    font-size: 14px;
}
.btn-primary{
     background-color: #f36;
     color: #fff;
     @extend .btn;
}
.btn-second{
      background-color: orange;
      color: #fff;
      @extend .btn;
}

编译出来之后:

//CSS
.btn, .btn-primary, .btn-second{
    border: 1px solid #ccc;
    padding: 6px 10px;
    font-size: 14px;
}
.btn-primary{
     background-color: #f36;
     color: #fff;
}
.btn-second{
      background-color: orange;
      color: #fff;
}

从示例代码可以看出,在Sass中的继承,可以继承类样式块中所有样式代码,而且编译出来的CSS会将选择器合并在一起,形成组合选择器:

.btn, .btn-primary, .btn-second{
        border: 1px solid #ccc;
        padding: 6px 10px;
        font-size: 14px;
}

占位符%placeholder

Sass中的占位符%placeholder功能是一个很强大、很实用的一个功能,他可以取代以前CSS中的基类造成的代码冗余的情形。因为%placeholder声明的代码,如果不被@extend调用的话,不会产生任何代码。示例:

%mt5{
    margin-top: 5px;
}
%pt5{
    padding-top: 5px;
}

这段代码没有被@extend调用,他并没有产生任何代码块,只是静静的躺在你的某个SCSS文件中。只有通过@extend调用才会产生代码:

//SCSS
%mt5{
      margin-top: 5px;
}
%pt5{
      padding-top: 5px;
}
.btn{
      @extend %mt5;
      @extend %pt5;
}
.block{
        @extend %mt5;
        span{
              @expend %pt5;
        }
}

编译出来的CSS

//CSS
.btn, .block{
      margin-top: 5px;
}
.btn, .block span{
    padding-top: 5px;
}

从编译出来的CSS代码可以看出,通过@expend调用的占位符,编译出来的代码会将相同的代码合并在一起。这也是我们希望看到的效果,也让你的代码变的更为干净。

混合宏 VS 继承 VS 占位符

a)混合宏的使用
如果你的代码块中涉及到变量,建议使用混合宏来创建相同的代码块。

b)Sass 继承
如果你的代码块不需要传任何变量参数,而且有一个基类已在文件中存在,那么建议使用Sass继承

c)占位符
编译出来的 CSS 代码和使用继承基本上是相同,只是不会在代码中生成占位符 mt 的选择器。那么占位符和继承的主要区别的,“占位符是独立定义,不调用的时候是不会在 CSS 中产生任何代码;继承是首先有一个基类存在,不管调用与不调用,基类的样式都将会出现在编译出来的 CSS 代码中。”

Paste_Image.png

插值#{}

使用CSS预处理器语言的一个主要原因是想使用Sass获得一个更好的结构体系。比如说你想写更干净的、高效的和面向对象的CSS。Sass中的插值就是重要的一部分。示例:

$properties: (margin, padding);
@mixin set-value($side, $value){
    @each $prop in $properties{
               #{$prop}-#{side}: $value; 
      }
}
.login-box{
      @include set-value(top, 14px);
]

它可以让变量和属性工作的很完美,上面的代码编译成CSS:

.login-box{
    margin-top: 14px;
    padding-top: 14px;
}

这是Sass插值中的一个简单的实例。当你想设置属性值的时候你可以使用字符串插入进来。另一个有用的用法是构建一个选择器。可以这样使用:

@mixin generate-sizes($class, $small, $medium, $big){
    .#{$class}-small {font-size: $small;}
    .#{$class}-medium{font-size: $medium;}
    .#{$class}-big{font-size: $big;}
}
@include generate-sizes("header-text", 12px, 20px, 40px);

编译出来的CSS:

.header-text-small {font-size:12px;}
.header-text-medium {font-size:20px;}
.header-text-big{font-size: 40px;}
$margin-big: 40px;
$margin-medium: 20px;
$margin-small: 12px;
@mixin set-value($size){
      margin-top: $margin-#{$size};
}
.login-box{
      @include set-value(big);
}

上面的Sass代码编译出来,你会得到下面的信息:

error style.scss (Line 5: Undefined variable: “$margin-".)

所以,#{}语法并不是随处可用,你也不能在mixin中调用:

@mixin updated-status {
    margin-top: 20px;
    background: #F00;
}
$flag: "status";
.navigation {
    @include updated-#{$flag};
}

上面的代码在编译成 CSS 时同样会报错:

error style.scss (Line 7: Invalid CSS after "...nclude updated-": expected "}", was "#{$flag};")

幸运的是,可以使用 @extend 中使用插值。例如:

%updated-status {
    margin-top: 20px;
    background: #F00;
}
.selected-status {
    font-weight: bold;
}
$flag: "status";
.navigation {
    @extend %updated-#{$flag};
    @extend .selected-#{$flag};
}

上面的 Sass 代码是可以运行的,因为他给了我们力量,可以动态的插入 .class 和 %placeholder。当然他们不能接受像 mixin 这样的参数,上面的代码编译出来的 CSS:

.navigation {
    margin-top: 20px;
    background: #F00;
}
.selected-status, .navigation {
    font-weight: bold;
}

在 Sass 的社区正在积极讨论插值的局限性,谁又知道呢,也许我们很快将能够使用这些技术也说不定呢。

注释

Sass有两种注释方式,暂且将其命名为:
1.块注释"/*......... */"
2.行注释 "//"
两者区别,前者会在编译出来的CSS显示,后者在编译出来的CSS中不会显示,示例:

//定义一个占位符
%mt5{
      margin-top: 5px;
}

/*调用一个占位符*/
.box{
      @extend %mt5;
}

编译出来的CSS

.box{
    margin-top: 5px;
}

/*调用一个占位符*/
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • 声明变量 定义变量的语法: 在有些编程语言中(如,JavaScript)声明变量都是使用关键词“var”开头,但是...
    Junting阅读 1,469评论 0 6
  • 1、SCSS 是 Sass 的新语法格式,从外形上来判断他和 CSS 长得几乎是一模一样,代码都包裹在一对大括号里...
    夜幕小草阅读 1,707评论 2 10
  • 基础 声明变量 普通变量 默认变量 变量覆盖:只需要在默认变量之前重新声明下变量即可 变量的调用 局部变量和全局变...
    Jill1231阅读 1,270评论 0 1
  • 前言 什么是CSS预处理器 定义:CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为CSS增...
    SA_Arthur阅读 3,117评论 0 18
  • 初夏的太阳让久居寒冬的我们心里感到一丝丝躁动。慵懒的神经开始发挥本性,每天早晨都要睡到上课迟到的时候。感觉自己的大...
    闭嘴吧猴头阅读 359评论 2 0