sass有哪些用法

准备工作

1、全局安装sass

npm install -g sass

2、在本地文件夹中新建index.scss、index.html

3、初始化package.json。并且安装sass

npm init -y

4、在index.scss中写入scss语法样式。执行编译语句

sass index.scss output.css

5、在output.css可以看见编译过来的scss样式。

6、在index.html中引入output.css,即可看见样式效果

嵌套

#main {
    width: 97%;
    .content{
        background-color: orange;
        .title{
            font-weight: 900;
            i{
                font-size: 30px;
            }
        }
    }
}
#main {
  width: 97%;
}
#main .content {
  background-color: orange;
}
#main .content .title {
  font-weight: 900;
}
#main .content .title i {
  font-size: 30px;
}

属性嵌套

CSS在“名称空间”中有很多属性。例如font-family,font-size和font-weight都在font命名空间。在CSS中,如果你想在同一个命名空间中设置一堆属性,你必须每次输入它。Sass为此提供了一个快捷方式:只需写一次名称空间,然后在其中嵌套每个子属性。例如:

.funky {
  font: {
    family: fantasy;
    size: 30em;
    weight: bold;
  }
  background: {
      color: red;
      size: 100% 100%;
      position: center;
  }
}
.funky {
  font-family: fantasy;
  font-size: 30em;
  font-weight: bold;
  background-color: red;
  background-size: 100% 100%;
  background-position: center;
}

引用父选择器:&

普通引用父选择器

有时候,使用嵌套规则的父选择器的方式与默认方式不同。例如:hover。

#main {
  color: black;
  a {
    font-weight: bold;
    &:hover { color: red; }
  }
}
#main {
  color: black;
}
#main a {
  font-weight: bold;
}
#main a:hover {
  color: red;
}

复合选择器

#main {
    color: black;
    &-content {
        border: 1px solid;
        &-title{
            font-weight: 800;
            &-icon{
                font-size: 40px;
            }
        }
    }
}
#main {
  color: black;
}
#main-content {
  border: 1px solid;
}
#main-content-title {
  font-weight: 800;
}
#main-content-title-icon {
  font-size: 40px;
}

注释:/* */和//

Sass支持标准的多行CSS注释/* */,以及单行注释//。多行注释尽可能保留在CSS输出中,而单行注释则被删除。例如:

/* This comment is
 * several lines long.
 * since it uses the CSS comment syntax,
 * it will appear in the CSS output. */

// font serise
// font serise
body{ color: red }
/* This comment is
 * several lines long.
 * since it uses the CSS comment syntax,
 * it will appear in the CSS output. */
body {
  color: red;
}

多行注释插值

$version: "1.2.3";
/* This CSS is generated by My Snazzy Framework version #{$version}. */
body{
    padding: 0;
}
/* This CSS is generated by My Snazzy Framework version 1.2.3. */
body {
  padding: 0;
}

插值:

您可以使用#{}插值语法在选择器和属性名称中使用SassScript变量:

$name: foo;
$attr: border;
p.#{$name} {
  #{$attr}-color: blue;
}
p.foo {
  border-color: blue;
}

也可以使用#{}将SassScript放入属性值中。在大多数情况下,这并不比使用变量更好,但使用#{}意味着它附近的任何操作都将被视为纯CSS。例如:

p {
    $font-size: 12px;
    $line-height: 30px;
    font: #{$font-size}/#{$line-height};
}
p {
  font: 12px/30px;
}

@import

Sass扩展了CSS @import规则,允许它导入SCSS和Sass文件。所有导入的SCSS和Sass文件将合并成一个CSS输出文件。另外,在主文件中可以使用在导入文件中定义的任何变量或mixin。

@import "foo";

或者同时导入多个

@import "rounded-corners", "text-shadow";
  • 嵌套@import

如果demo.scss包含

.demo{
    color: red;
}

然后

#app{
    font-weight: 800;
    @import "./demo.scss";
}

@use

该 @use 规则从其他 Sass 样式表中加载混合、函数和变量,并将来自多个样式表的 CSS 组合在一起。加载的 @use 样式表称为“模块”。Sass 还提供了充满有用功能的内置模块。

// foundation/_code.scss
code {
  padding: .25em;
  line-height: 0;
}
// foundation/_lists.scss
ul, ol {
  text-align: left;

  & & {
    padding: {
      bottom: 0;
      left: 0;
    }
  }
}
// style.scss
@use 'foundation/code';
@use 'foundation/lists';
code {
  padding: .25em;
  line-height: 0;
}

ul, ol {
  text-align: left;
}
ul ul, ol ol {
  padding-bottom: 0;
  padding-left: 0;
}
  • 模块使用

默认模块名为文件名字"src/corners"; => corners

// src/_corners.scss
$radius: 3px;

@mixin rounded {
  border-radius: $radius;
}
// style.scss
@use "src/corners";

.button {
  @include corners.rounded;
  padding: 5px + corners.$radius;
}
.button {
  border-radius: 3px;
  padding: 8px;
}
  • 修改模块名
// src/_corners.scss
$radius: 3px;

@mixin rounded {
  border-radius: $radius;
}
// style.scss
@use "src/corners" as c;

.button {
  @include c.rounded;
  padding: 5px + c.$radius;
}
.button {
  border-radius: 3px;
  padding: 8px;
}
  • as *

您甚至可以通过编写@use "<url>" as * 不过,我们建议您只对您编写的样式表执行此操作;否则,他们可能会引入导致名称冲突的新成员!

// src/_corners.scss
$radius: 3px;

@mixin rounded {
  border-radius: $radius;
}
// style.scss
@use "src/corners" as *;

.button {
  @include rounded;
  padding: 5px + $radius;
}
.button {
  border-radius: 3px;
  padding: 8px;
}
  • Sass 使定义私有成员
// src/_corners.scss
$-radius: 3px;

@mixin rounded {
  border-radius: $-radius;
}
// style.scss
@use "src/corners";

.button {
  @include corners.rounded;

  // This is an error! $-radius isn't visible outside of `_corners.scss`.
  padding: 5px + corners.$-radius;
}
  • !default
// _library.scss
$black: #000 !default;
$border-radius: 0.25rem !default;
$box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default;

code {
  border-radius: $border-radius;
  box-shadow: $box-shadow;
}
// style.scss
@use 'library' with (
  $black: #222,
  $border-radius: 0.1rem
);
code {
  border-radius: 0.1rem;
  box-shadow: 0 0.5rem 1rem rgba(34, 34, 34, 0.15);
}
  • With Mixins

使用 配置模块非常方便,尤其是在使用最初为使用 @use ... with @import 规则而编写的库时。但它不是特别灵活,我们不建议将其用于更高级的用例。如果您发现自己想要一次配置多个变量,将映射作为配置传递,或者在加载模块后更新配置,请考虑编写一个 mixin 来设置变量,并编写另一个 mixin 来注入您的样式。

// _library.scss
$-black: #000;
$-border-radius: 0.25rem;
$-box-shadow: null;

/// If the user has configured `$-box-shadow`, returns their configured value.
/// Otherwise returns a value derived from `$-black`.
@function -box-shadow() {
  @return $-box-shadow or (0 0.5rem 1rem rgba($-black, 0.15));
}

@mixin configure($black: null, $border-radius: null, $box-shadow: null) {
  @if $black {
    $-black: $black !global;
  }
  @if $border-radius {
    $-border-radius: $border-radius !global;
  }
  @if $box-shadow {
    $-box-shadow: $box-shadow !global;
  }
}

@mixin styles {
  code {
    border-radius: $-border-radius;
    box-shadow: -box-shadow();
  }
}
// style.scss
@use 'library';

@include library.configure(
  $black: #222,
  $border-radius: 0.1rem
);

@include library.styles;
  • 重新分配变量
// _library.scss
$color: red;
// _override.scss
@use 'library';
library.$color: blue;
// style.scss
@use 'library';
@use 'override';
@debug library.$color;  //=> blue

区别 @import

  • 该 @use 规则旨在替换旧 @import 规则,但它有意设计为以不同的方式工作。以下是两者之间的一些主要区别:
    • @use 仅使变量、函数和混合在当前文件的范围内可用。它永远不会将它们添加到全局范围。这使得很容易弄清楚您的 Sass 文件引用的每个名称来自哪里,并且意味着您可以使用较短的名称而不会有任何冲突风险。
    • @use 每个文件只加载一次。这可确保您最终不会意外地多次复制依赖项的 CSS。
    • @use 必须出现在文件的开头,并且不能嵌套在样式规则中。
    • 每个 @use 规则只能有一个 URL。
    • @use 需要在其 URL 两边加上引号,即使在使用缩进语法时也是如此。

@forward

// src/_list.scss
@mixin list-reset {
  margin: 0;
  padding: 0;
  list-style: none;
}
// bootstrap.scss
@forward "src/list";
// styles.scss
@use "bootstrap";

li {
  @include bootstrap.list-reset;
}
li {
  margin: 0;
  padding: 0;
  list-style: none;
}
  • 添加前缀
// src/_list.scss
@mixin reset {
  margin: 0;
  padding: 0;
  list-style: none;
}
// bootstrap.scss
@forward "src/list" as list-*;
// styles.scss
@use "bootstrap";

li {
  @include bootstrap.list-reset;
}
li {
  margin: 0;
  padding: 0;
  list-style: none;
}
  • 控制可见性
// src/_list.scss
$horizontal-list-gap: 2em;

@mixin list-reset {
  margin: 0;
  padding: 0;
  list-style: none;
}

@mixin list-horizontal {
  @include list-reset;

  li {
    display: inline-block;
    margin: {
      left: -2px;
      right: $horizontal-list-gap;
    }
  }
}
// bootstrap.scss
@forward "src/list" hide list-reset, $horizontal-list-gap;
  • 配置模块
// _library.scss
$black: #000 !default;
$border-radius: 0.25rem !default;
$box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default;

code {
  border-radius: $border-radius;
  box-shadow: $box-shadow;
}
// _opinionated.scss
@forward 'library' with (
  $black: #222 !default,
  $border-radius: 0.1rem !default
);

```scss
// style.scss
@use 'opinionated' with ($black: #333);

@media

Sass中的指令就像它们在纯CSS中一样,具有一个额外的功能:它们可以嵌套在CSS规则中。如果@media指令出现在CSS规则中,它将冒泡到样式表的顶层,将所有选择器放在规则内。这样可以轻松添加媒体特定的样式,而无需重复选择器或中断样式表的流程。

.sidebar {
  width: 300px;
  @media screen and (orientation: landscape) {
    width: 500px;
  }
}
.sidebar {
  width: 300px;
}
@media screen and (orientation: landscape) {
  .sidebar {
    width: 500px;
  }
}

@extend

这个指令是非常有用的。

当一个类应该具有另一个类的所有样式以及它自己的特定样式时,经常会有设计页面的情况。处理这种情况的最常见方式是在HTML中使用更一般的类和更具体的类。例如,假设我们设计了一个正常的错误,并且还有一个严重的错误。我们可能会这样写我们的标记:

<div class="error seriousError">
  Oh no! You've been hacked!
</div>

我们的风格如下:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  border-width: 3px;
}

不幸的是,这意味着我们必须永远记住使用.seriousErro时需要参考.error的样式。这是一个维护负担,会导致棘手的错误,并且可能会将非语义风格问题带入标记。

@extend通过告诉Sass一个选择器应该继承另一个选择器的样式,该指令避免了这些问题。例如:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}
.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd;
}

.seriousError {
  border-width: 3px;
}
  • 多重扩展

一个选择器可以扩展多个选择器。这意味着它继承了所有扩展选择器的样式。例如:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.attention {
  font-size: 3em;
  background-color: #ff0;
}
.seriousError {
  @extend .error;
  @extend .attention;
  border-width: 3px;
}
.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd;
}

.attention, .seriousError {
  font-size: 3em;
  background-color: #ff0;
}

.seriousError {
  border-width: 3px;
}

Maps

那么Sass的map长得与JSON极其相似:

$map: (
    $key1: value1,
    $key2: value2,
    $key3: value3
)

对于Sass的map,还可以让map嵌套map。其实就是map的某一个key当成map,里面可以继续放一对或者多对key:value:

$map: (
    key1: value1,
    key2: (
        key-1: value-1,
        key-2: value-2,
    ),
    key3: value3
);

Sass Maps的函数

  • 前面介绍了使用map来管理变量,但要在Sass中获取变量,或者对map做更多有意义的操作,我们必须借助于map的函数功能。在Sass中map自身带了七个函数:
    • map-get($map,$key):根据给定的key值,返回map中相关的值。
    • map-merge($map1,$map2):将两个map合并成一个新的map。
    • map-remove($map,$key):从map中删除一个key,返回一个新map。
    • map-keys($map):返回map中所有的key。
    • map-values($map):返回map中所有的value。
    • map-has-key($map,$key):根据给定的key值判断map是否有对应的value值,如果有返回true,否则返回false。
    • keywords($args):返回一个函数的参数,这个参数可以动态的设置key和value。

接下来,我们先简单的了解这些函数的具体使用以及所具有的功能。

map-get($map,$key)

  • map-get($map,$key)函数的作用是根据$key参数,返回$key在$map中对应的value值。如果$key不存在$map中,将返回null值。此函数包括两个参数:
    • $map:定义好的map。
    • $key:需要遍历的key。

来看一个简单的示例,假设定义了一个$social-colors的map:

$social-colors: (
    dribble: #ea4c89,
    facebook: #3b5998,
    github: #171515,
    google: #db4437,
    twitter: #55acee
);

假设要获取facebook键值对应的值#3b5998,我们就可以使用map-get()函数来实现:

.btn-dribble{
  color: map-get($social-colors,facebook);
}

编译出来的CSS:

.btn-dribble {
  color: #3b5998;
}

我们来看另一种情况,假设$social-colors这个map没有$weibo这个key:

.btn-weibo{
  font-size: 12px;
  color: map-get($social-colors,weibo);
}

此时编译出来的是CSS:

.btn-weibo {
  font-size: 12px;
}

从编译出来的CSS可以得知,如果$key不在$map中,不会编译出CSS,其实在Sass中,map-get($social-colors,weibo)返回了一个null值。但在编译出来的CSS中,你只知道他没有编译出样式,而且在命令终端编译时,也没有任何错误或者警告信息。说实话,你并不知道他为什么编译不出来样式,或者说他已返回了值为null。体验不强,也不好排错。其实哪果我们自定义一个函数,另外加个判断,那就截然不同。

map-has-key($map,$key)

map-has-key($map,$key)函数将返回一个布尔值。当$map中有这个$key,则函数返回true,否则返回false。

前面的示例,当$key不在$map中时,使用map-get($map,$key)函数将返回一个null值。但对于开发人员,并看不到任何提示信息。如果使用map-has-key($map,$key)函数就可以改变这一状态。我们来看一个简单的示例。

@if map-has-key($social-colors,facebook){
    .btn-facebook {
        color: map-get($social-colors,facebook);
    }
} @else {
    @warn "No color found for faceboo in $social-colors map. Property ommitted."
}

编译出来:

.btn-fackbook{
    color: #3b5998;
}

上面看到的示例是facebook这个key已存在$social-colors这个map当中。所以能正常编译。如果你手误,将facebook输错了:

@if map-has-key($social-colors,faceboo){
    .btn-facebook {
        color: map-get($social-colors,facebook);
    }
} @else {
    @warn "No color found for faceboo in $social-colors map. Property ommitted."
}

这个时候,你编译出来的CSS代码中,不会有新代码添加,但在命令终端可以看到提示信息:

WARNING: No color found for faceboo in $social-colors map. Property ommitted.
         on line 25 of test.scss

是不是非常的友好。但总觉得这样写是傻傻的,总不可能每获取一个key都写一个@if语句吧。其实不用这么复杂,我们可以自定义一个函数,比如colors():

@function colors($color){
    @if not map-has-key($social-colors,$color){
        @warn "No color found for `#{$color}` in $social-colors map. Property omitted.";
    }
    @return map-get($social-colors,$color);
}

有了这个函数之后,我们就可以这样使用:

.btn-dribble {
    color: colors(dribble);
}
.btn-facebook {
    color: colors(facebook);
}
.btn-github {
    color: colors(github);
}
.btn-google {
    color: colors(google);
}
.btn-twitter {
    color: colors(twitter);
}
.btn-weibo {
    color: colors(weibo);
}

编译出来的CSS:

.btn-dribble {
  color: #ea4c89;
}

.btn-facebook {
  color: #3b5998;
}

.btn-github {
  color: #171515;
}

.btn-google {
  color: #db4437;
}

.btn-twitter {
  color: #55acee;
}

同时你不难发现,命令终端提示信息:

WARNING: No color found for `weibo` in $social-colors map. Property omitted.
         on line 13 of test.scss

那是在$social-colors这个map中没有weibo这个key。是不是很有意思。

当然,如果你对Sass的指令熟悉的话,上面编译出来的CSS可以使用@each:

@each $social-network,$social-color in $social-colors {
    .btn-#{$social-network} {
        color: colors($social-network);
    }
}

map-keys($map)

map-keys($map)函数将会返回$map中的所有key。这些值赋予给一个变量,那他就是一个列表。如:

map-keys($social-colors);

其返回的值为:

"dribble","facebook","github","google","twitter"

换句话说:

$list: map-keys($social-colors);

相当于:

$list:"dribble","facebook","github","google","twitter";

这个时候,就可以配合Sass的list做很多事情。

上面的示例,可以做通过map-keys($map)来做一个修改:

@function colors($color){
    $names: map-keys($social-colors);
    @if not index($names, $color){
        @warn "Waring: `#{$color} is not a valid color name.`";
    }
    @return map-get($social-colors,$color);
}

上面代码中最不同之处,我们使用map-keys将$social-colors这个map的所有key取出,并赋予给一个名为$names的列表。然后通过index($names,$color)返回$color在$names位置,如果这个位置不存在,将返回提示信息,如果存在将返回正确的值。

.btn-weibo{
    color: colors(weibo);
}

例如,weibo不在$social-colors中,那么不会编译出CSS,而且在命令终端同样会有提示信息:

WARNING: Waring: `weibo is not a valid color name.`
         on line 27 of test.scss

同样,也可以通过@each或者@for遍历出所有值:

@each

@each $name in map-keys($social-colors){
    .btn-#{$name}{
        color: colors($name);
    }
}

@for

@for $i from 1 through length(map-keys($social-colors)){
    .btn-#{nth(map-keys($social-colors),$i)} {
        color: colors(nth(map-keys($social-colors),$i));
    }
}

虽然使用的方法不一样,但最终得到的CSS是一样的:

.btn-dribble {
  color: #ea4c89;
}

.btn-facebook {
  color: #3b5998;
}

.btn-github {
  color: #171515;
}

.btn-google {
  color: #db4437;
}

.btn-twitter {
  color: #55acee;
}

map-values($map)

map-values($map)函数类似于map-keys($map)功能,不同的是map-values($map)获取的是$map的所有value值,可以说也将是一个列表。而且,map-values($map)中如果有相同的value也将会全部获取出来。

如前面的示例,使用:

map-values($social-colors)

将会返回:

#ea4c89,#3b5998,#171515,#db4437,#55acee

值与值之前同样用逗号分隔。

map-merge($map1,$map2)

map-merge($map1,$map2)函数是将$map1和$map2合并,然后得到一个新的$map。如果你要快速将新的值插入到$map中的话,这种方法是最佳方法。假设我们有两个$map:

$color: (
    text: #f36,
    link: #f63,
    border: #ddd,
    backround: #fff
);
$typo:(
    font-size: 12px,
    line-height: 1.6
);

如果希望将这两个$map合并成一个map,我们只要这样做:

$newmap: map-merge($color,$typo);

将会生成一个新的map:

$newmap:(
    text: #f36,
    link: #f63,
    border: #ddd,
    background: #fff,
    font-size: 12px,
    line-height: 1.6
);

这样你就可以借助map-get()等函数做其他事情了。

不过有一点需要注意,如果$map1和$map2中有相同的$key名,那么将$map2中的$key会取代$map1中的:

$color: (
    text: #f36,
    link: #f63,
    border: #ddd,
    backround: #fff
);
$typo:(
    font-size: 12px,
    line-height: 1.6,
    border: #ccc,
    background: #000
);

执行:

$newmap: map-merge($color,$typo);

得到的新map:

$newmap:(
    text: #f36,
    link: #f63,
    font-size: 12px,
    line-height: 1.6,
    border: #ccc,
    background: #000
);

map-remove($map,$key)

map-remove($map,$key)函数是用来删除当前$map中的某一个$key,从而得到一个新的map。其返回的值还是一个map。map-remove($map,$key)并不能直接从一个map中删除另一个map,仅能通过删除map中的某个key得到新map。如:

$map:map-remove($social-colors,dribble);

返回的是一个新map:

$map:(
    facebook: #3b5998,
    github: #171515,
    google: #db4437,
    twitter: #55acee
);

如果删除的key并不存在于$map中,那么map-remove()函数返回的新map和以前的map一样。

$map:map-remove($social-colors,weibo);

返回的值:

$map: (
    dribble: #ea4c89,
    facebook: #3b5998,
    github: #171515,
    google: #db4437,
    twitter: #55acee
);

keywords($args)

keywords($args)函数可以说是一个动态创建map的函数。可以通过混合宏或函数的参数变创建map。参数也是成对出现,其中$args变成key(会自动去掉$符号),而$args对应的值就是value。

@mixin map($args...){
    @debug keywords($args);
}

@include map(
  $dribble: #ea4c89,
  $facebook: #3b5998,
  $github: #171515,
  $google: #db4437,
  $twitter: #55acee
);

在命令终端可以看到一个输入的@debug信息:

 DEBUG: (dribble: #ea4c89, facebook: #3b5998, github: #171515, google: #db4437, twitter: #55acee)

控制指令和表达

SassScript支持基本的控制指令和表达式,仅用于在某些情况下包含样式,或者在变体中多次包含相同样式。

if()函数

可以将if函数看作为3个参数。if(condition, trueValue, otherValue)。trueValue、otherValue可以是任何 Sass 值,例如颜色、字体大小、间距等。

$font-size: 16px;
$breakpoint: 768px;

.title {
  font-size: if($breakpoint >= 768px, 24px, $font-size);
    i{
        font-size: if($breakpoint > 768px, 24px, $font-size);
    }
}
.title {
  font-size: 24px;
}
.title i {
  font-size: 16px;
}

@if指令

@if声明可以由几个@else if语句,一个@else声明。如果@if陈述失败,@else if则按顺序尝试陈述,直到成功或@else达到陈述。例如:

$type: monster;
p {
  @if $type == ocean {
    color: blue;
  } @else if $type == matador {
    color: red;
  } @else if $type == monster {
    color: green;
  } @else {
    color: black;
  }
}
p {
  color: green;
}

@for指令

@for指令重复输出一组样式。对于每次重复,计数器变量用于调整输出。该指令有两种形式:

@for $var from [start] through [end]

@for $var from [start] to [end]

$var可以是任何变量名称。[start]并且[end]是应该返回整数的SassScript表达式。

  • 请注意关键字through和区别to
@for $i from 1 to 3 {
    .item-#{$i} {
        width: 2px * $i
    }
}
.item-1 {
  width: 2px;
}

.item-2 {
  width: 4px;
}
@for $i from 1 through 3 {
    .row-#{$i} {
        height: 2px * $i
    }
}
.row-1 {
  height: 2px;
}

.row-2 {
  height: 4px;
}

.row-3 {
  height: 6px;
}

得到:具有以下形式from ... through,所述范围包括的值[start][end],但形式from ... to运行至但不包括的值[end]

  • 递减|递增
@for $i from 1 through 2 {
    .item-#{$i} {
        width: 2px * $i
    }
}

@for $i from 2 through 1 {
    .item-#{$i} {
        width: 2px * $i
    }
}
.item-1 {
  width: 2px;
}

.item-2 {
  width: 4px;
}

.item-2 {
  width: 4px;
}

.item-1 {
  width: 2px;
}

所以:start > end ? 递减 : 递增

@each指令

@each指令的格式是$var in list

@each $animal in puma, sea-slug, egret, salamander {
    .#{$animal}-icon {
        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");
}
  • @each指令也可以使用多个变量

in @each var2, ... in list。如果list是列表列表,则将子列表的每个元素分配给相应的变量。例如:

@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;
}
  • @while指令

@while指令采用SassScript表达式并重复输出嵌套样式,直到语句求值为止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;
}

混合指令#mixins

Mixins允许您定义可以在整个样式表中重用的样式,而无需使用类似的非语义类.float-left。

指令定义

Mixins由@mixin指令定义。它后面跟着mixin的名称和可选的参数,以及一个包含mixin内容的块。例如,large-textmixin定义如下:

@mixin large-text {
    font: {
        family: Arial;
        size: 20px;
        weight: bold;
    }
    color: #ff0000;
}

引用mixins

Mixins包含在@include指令文档中。这需要一个mixin的名称和可选的参数传递给它,并将该mixin定义的样式包含到当前规则中。例如:

@mixin large-text {
    font: {
        family: Arial;
        size: 20px;
        weight: bold;
    }
    color: #ff0000;
}

.page-title {
    @include large-text;
    padding: 4px;
    margin-top: 10px;
}
.page-title {
  font-family: Arial;
  font-size: 20px;
  font-weight: bold;
  color: #ff0000;
  padding: 4px;
  margin-top: 10px;
}

只要不直接定义任何属性或使用任何父引用,Mixin也可以包含在任何规则之外(即,位于文档的根目录)。例如:

@mixin silly-links {
  a {
    color: blue;
    background-color: red;
  }
}

@include silly-links;
a {
  color: blue;
  background-color: red;
}

mixins参数

Mixin可以将SassScript值作为参数,当mixin被包含并在mixin中作为变量提供时,会给出这些参数。

@mixin sexy-border($color, $width) {
  border: {
    color: $color;
    width: $width;
    style: dashed;
  }
}

p { @include sexy-border(blue, 1in); }
p {
  border-color: blue;
  border-width: 1in;
  border-style: dashed;
}

同理,还支持参数默认值

@mixin sexy-border($color, $width: 1in) {
    border: {
        color: $color;
        width: $width;
        style: dashed;
    }
}

p {
    @include sexy-border(blue);
}

h1 {
    @include sexy-border(blue, 2in);
}
p {
  border-color: blue;
  border-width: 1in;
  border-style: dashed;
}

h1 {
  border-color: blue;
  border-width: 2in;
  border-style: dashed;
}

将内容块传递给Mixin

除了上面传递参数给mixin,还可以传整个内容块

@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或者函数需要一些未知数的参数是有意义的。例如,用于创建框阴影的混合可能会将任意数量的阴影作为参数。对于这些情况,Sass支持“可变参数”,这些参数是混合函数或函数声明结尾的参数,它们将所有剩余的参数作为列表打包。这些论点看起来就像正常的论点,但后面跟着...。例如:

@mixin box-shadow($shadows...) {
  -moz-box-shadow: $shadows;
  -webkit-box-shadow: $shadows;
  box-shadow: $shadows;
}

.shadows {
  @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}
.shadows {
  -moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  -webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}

函数指令

可以在sass中定义自己的函数,并在任何值或脚本环境中使用它们。例如:

$grid-width: 40px;
$gutter-width: 10px;

@function grid-width($n) {
  @return $n * $grid-width + ($n - 1) * $gutter-width;
}

#sidebar { width: grid-width(5); }
#sidebar {
  width: 240px;
}

正如你所看到的,函数可以访问任何全局定义的变量以及像mixin一样接受参数。一个函数可能包含多个语句,并且您必须调用@return以设置该函数的返回值。

与mixin一样,您可以使用关键字参数调用Sass定义的函数。在上面的例子中,我们可以像这样调用函数:

#sidebar { width: grid-width($n: 5); }

Sass函数

字符串函数

  • 字符串函数顾名思意是用来处理字符串的函数。Sass的字符串函数主要包括两个函数:
    • unquote($string):删除字符串中的引号;
    • quote($string):给字符串添加引号。

数字函数

  • Sass中的数字函数提要针对数字方面提供一系列的函数功能:
    • percentage($value):将一个不带单位的数转换成百分比值;
    • round($value):将数值四舍五入,转换成一个最接近的整数;
    • ceil($value):将大于自己的小数转换成下一位整数;
    • floor($value):将一个数去除他的小数部分;
    • abs($value):返回一个数的绝对值;
    • min($numbers…):找出几个数值之间的最小值;
    • max($numbers…):找出几个数值之间的最大值。

看到上面函数的简介,对于熟悉javascript同学而言并不会感觉陌生。因为他们有很多功能都非常类似,接下来对每个函数进行一些简单的测试。

List函数

  • 列表函数主要包括一些对列表参数的函数使用,主要包括以下几种:
    • length($list):返回一个列表的长度值;
    • nth($list, $n):返回一个列表中指定的某个标签值
    • join($list1, $list2, [$separator]):将两个列给连接在一起,变成一个列表;
    • append($list1, $val, [$separator]):将某个值放在列表的最后;
    • zip($lists…):将几个列表结合成一个多维的列表;
    • index($list, $value):返回一个值在列表中的位置值。

列表函数中的每个函数都有其独特的作用与功能,接下来我们通过命令终端向大家展示每个列表函数的功能与使用。

Introspection函数

  • Introspection函数包括了几个判断型函数:
    • type-of($value):返回一个值的类型
    • unit($number):返回一个值的单位;
    • unitless($number):判断一个值是否带有带位
    • comparable($number-1, $number-2):判断两个值是否可以做加、减和合并

这几个函数主要用来对值做一个判断的作用,依次来看每个函数的功能。

type-of()函数主要用来判断一个值是属于什么类型:

>> type-of(100)
"number"
>> type-of(100px)
"number"
>> type-of("asdf")
"string"
>> type-of(asdf)
"string"
>> type-of(true)
"bool"
>> type-of(false)
"bool"
>> type-of(#fff)
"color"
>> type-of(blue)
"color"
>> type-of(1 / 2 = 1)
"string"

自定义函数

自定义函数是用户根据自己一些特殊的需求编写的Sass函数。在很多时候,Sass自带的函数并不能满足功能上的需求,所以很多时候需要自定义一些函数。

例如,我们需要去掉一个值的单位,在这种情形之下,Sass自带的函数是无法帮助我们完成,这个时候我们就需要定义函数:

//去掉一个值的单位,如12px => 12
// eg. strip-units(12px) => 12

@function strip-units($number){
    @return $number / ($number * 0 + 1);
}

颜色函数

RGB颜色函数

  • rgb颜色只是颜色中的一种表达方式,其中R是“red"表示红色,而G是“green”绿色,B是“blue”蓝色。在Sass中为RGB颜色提供六种函数:
    • rgb($red,$green,$blue):根据红、绿、蓝三个值创建一个颜色;
    • rgba($red,$green,$blue,$alpha):根据红、绿、蓝和透明度值创建一个颜色;
    • red($color):从一个颜色中获取其中红色值;
    • green($color):从一个颜色中获取其中绿色值;
    • blue($color):从一个颜色中获取其中蓝色值;
    • mix($color-1,$color-2,[$weight]):把两种颜色混合在一起。

HSL颜色函数

HSL给我们带来了一个更直观的颜色控制,我们时常需要让一个颜色比另一个颜色更暗一点或者说更亮一点。比如说“a:hover”状态下我们需要把一个颜色变暗一点,那么使用“HSL”是非常方便的,反而我们使用十六进制那就需要更多的时间调试。而这个“HSL”他只是一个简单的数量变化。

  • saturation、lightness、adjust-hue、lighten、darken等等。接下来我们先来了解一下HSL颜色函数包括哪些具体的函数,所起的作用是什么。
    • hsl($hue,$saturation,$lightness):通过色相(hue)、饱和度(saturation)和亮度(lightness)的值创建一个颜色;
    • hsla($hue,$saturation,$lightness,$alpha):通过色相(hue)、饱和度(saturation)、亮度(lightness)和透明(alpha)的值创建一个颜色;
    • hue($color):从一个颜色中获取色相(hue)值;
    • saturation($color):从一个颜色中获取饱和度(saturation)值;
    • lightness($color):从一个颜色中获取亮度(lightness)值;
    • adjust-hue($color,$degrees):通过改变一个颜色的色相值,创建一个新的颜色;
    • lighten($color,$amount):通过改变颜色的亮度值,让颜色变亮,创建一个新的颜色;
    • darken($color,$amount):通过改变颜色的亮度值,让颜色变暗,创建一个新的颜色;
    • saturate($color,$amount):通过改变颜色的饱和度值,让颜色更饱和,从而创建一个新的颜色
    • desaturate($color,$amount):通过改变颜色的饱和度值,让颜色更少的饱和,从而创建出一个新的颜色;
    • grayscale($color):将一个颜色变成灰色,相当于desaturate($color,100%);
    • complement($color):返回一个补充色,相当于adjust-hue($color,180deg);
    • invert($color):反回一个反相色,红、绿、蓝色值倒过来,而透明度不变。

Opacity函数

在CSS中除了可以使用rgba、hsla和transform来控制颜色透明度之外,还可以使用opacity来控制,只不过前两者只是针对颜色上的透明通道做处理,而后者是控制整个元素的透明度。

  • 在Sass中,也提供了系列透明函数,只不过这系列的透明函数主要用来处理颜色透明度:
    • alpha($color) /opacity($color):获取颜色透明度值;
    • rgba($color, $alpha):改变颜色的透明度值;
    • opacify($color, $amount) / fade-in($color, $amount):使颜色更不透明;
    • transparentize($color, $amount) / fade-out($color, $amount):使颜色更加透明。

其他颜色函数

  • 除了上述介绍的函数之外,Sass还提供了其他的一些颜色函数:
    • adjust-color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha]):通过调整颜色一个属性或者多个属性获取新的颜色;
    • scale-color($color, [$red], [$green], [$blue], [$saturation], [$lightness], [$alpha]):通过调整颜色的一个属性或者多个属性获取一个流畅颜色;
    • change-color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha]):通过调整颜色的一个或者多个属笥获取一个新颜色;
    • ie-hex-str($color):将一个颜色转换成适合ie滤镜使用的颜色。

例子

// media.scss
$breakpoints: (
    'phone': (
        320px,
        480px
    ),
    'pad': (
        481px,
        768px
    ),
    'notebook': (
        769px,
        1024px
    ),
    'desktop': 1025px
);

@mixin respond-to($breakname) {
    $bp: map-get($breakpoints, $breakname);

    @if type-of($bp) == 'list' {
        $min: nth($bp, 1);
        $max: nth($bp, 2);

        @media (min-width: $min) and (max-width: $max) {
            @content;
        }
    } @else {
        @media (min-width: $bp) {
            @content;
        }
    }
}
// 使用
@include respond-to('desktop') {
    display: block;
}
贡献者: mankueng