什么是 Sass ?

Sass (Syntactically Awesome StyleSheets)是 CSS 的延伸,为基本语言增添了强大和优雅。 它允许您使用变量,嵌套规则,mixin,内联导入等,全部具有完全 CSS 兼容的语法。 Sass 有助于保持大型样式表的组织良好,并且可以快速获得小型样式表,特别是在 Compass 样式库的帮助下。

特性

  • 完全兼容 CSS
  • 语言扩展,如变量,嵌套和 mixin
  • 用于操作颜色和其他值的许多有用的函数
  • 高级功能,如库的控制指令
  • 格式良好,可定制的输出

语法

Sass 有两种语法。第一个,被称为 SCSS(Sassy CSS)并且在本参考文献中使用,是 CSS 的语法的扩展。这意味着每个有效的 CSS 样式表都是具有相同含义的有效的 SCSS 文件。此外,SCSS 了解大多数 CSS hack 和厂商特定的语法,例如 IE 的旧的 filter 语法。此语法通过下面描述的 Sass 特性得到增强。使用此语法的文件具有.scss扩展名。

第二个和较旧的语法,称为缩进语法(或有时仅仅叫「Sass」),提供了一种更简洁的编写 CSS 的方法。它使用缩进而不是括号来表示选择器的嵌套,使用换行符而不是分号来分隔属性。有些人认为这比 SCSS 更容易阅读和编写更快。缩进语法具有所有相同的功能,尽管其中一些语法略有不同;这在缩进的语法参考中有描述。使用此语法的文件具有.sass扩展名。

任何语法都可以导入另一个文件。文件可以使用sass-convert命令行工具自动从一种语法转换到另一种语法:

# 将 Sass 转换为 SCSS
$ sass-convert style.sass style.scss

# 将 SCSS 转换为 Sass
$ sass-convert style.scss style.sass

请注意,此命令_不生成 CSS_ 文件。为此,请使用其他地方描述的sass命令。

CSS 扩展

嵌套规则

Sass 允许 CSS 规则彼此嵌套。 内部规则只适用于外部规则的选择器。 例如:

#main p {
  color: #00ff00;
  width: 97%;

  .redbox {
    background-color: #ff0000;
    color: #000000;
  }
}

编译为:

#main p {
  color: #00ff00;
  width: 97%; }

  #main p .redbox {
    background-color: #ff0000;
    color: #000000; }

这有助于避免重复父选择器,并使复杂的 CSS 布局与许多嵌套选择器更简单。 例如:

#main {
  width: 97%;

  p, div {
    font-size: 2em;
    a { font-weight: bold; }
  }

  pre { font-size: 3em; }
}

编译为:

#main {
  width: 97%; }

  #main p, #main div {
    font-size: 2em; }

    #main p a, #main div a {
      font-weight: bold; }

  #main pre {
    font-size: 3em; }

引用父选择器:&

有时候,以其他方式使用嵌套规则的父选择器比默认的要好。 例如,您可能希望有一个特殊的样式,当该选择器悬停在或者当 body 元素具有某个类时。 在这些情况下,您可以使用 & 字符显式指定父选择器应在哪里插入。 例如:

a {
  font-weight: bold;
  text-decoration: none;
  &:hover { text-decoration: underline; }
  body.firefox & { font-weight: normal; }
}

编译为:

a {
  font-weight: bold;
  text-decoration: none; }

  a:hover {
    text-decoration: underline; }

  body.firefox a {
    font-weight: normal; }

CSS 中出现的 & 将被父选择器替换。 这意味着如果你有一个深层次的嵌套规则,父选择器将在 & 被替换之前被完全解决。 例如:

#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;
  &-sidebar { border: 1px solid; }
}

编译为:

#main {
  color: black; }

  #main-sidebar {
    border: 1px solid; }

如果父选择器不能应用后缀,则 Sass 将抛出一个错误。

嵌套属性

CSS 中有很多属性在「命名空间」中; 例如,font-familyfont-sizefont-weight都在font命名空间中。 在 CSS 中,如果要在同一个命名空间中设置一堆属性,则必须每次都键入它。 Sass 为此提供了一个快捷方式:只需编写一次命名空间,然后在其中嵌套每个子属性。 例如:

.funky {
  font: {
    family: fantasy;
    size: 30em;
    weight: bold;
  }
}

编译为:

.funky {
  font-family: fantasy;
  font-size: 30em;
  font-weight: bold; }

属性命名空间本身也可以有一个值。 例如:

.funky {
  font: 20px/24px fantasy {
    weight: bold;
  }
}

编译为:

.funky {
  font: 20px/24px fantasy;
    font-weight: bold;
}

占位符选择器:%foo

Sass 支持一种特殊类型的选择器,称为「占位符选择器」。 这些看起来像 class 和 id 选择器,除了用代替#.。 它们意味着要和@extend指令一起使用; 有关更多信息,请参阅@extend-Only选择器。

没有使用@extend的话,使用占位符选择器的规则集将不会呈现给 CSS。

注释:/* *///

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

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

// These comments are only one line long each.
// They won't appear in the CSS output,
// since they use the single-line comment syntax.
a { color: green; }

编译为:

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

a {
  color: green; }

当多行注释的第一个字母为!时,即使在压缩输出模式下,注释也将始终呈现为 css 输出。 这对将版权声明添加到生成的CSS中很有用。

由于多行注释成为最终 CSS 的一部分,因此可以解析其中插入的内容。 例如:

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

编译为:

/* This CSS is generated by My Snazzy Framework version 1.2.3. */

SassScript

除了纯 CSS 属性语法,Sass 还支持一小部分称为 SassScript 的扩展。 SassScript 允许属性使用变量,算术和额外的函数。 SassScript 可用于任何属性值。

SassScript 也可用于生成选择器和属性名称,这在编写 mixin 时非常有用。 这是通过插值(interpolation)完成的。

变量:$

使用 SassScript 最简单的方法是使用变量。 变量以美元符号开始,并像 CSS 属性一样设置:

$width: 5em;

然后,您可以在属性中引用它们:

#main {
  width: $width;
}

变量只能在定义它们的嵌套选择器的级别中使用。 如果它们被定义在任何嵌套选择器之外,它们可以随处可用。 它们也可以用!global标志来定义,在这种情况下,它们也可以随处可用。 例如:

#main {
  $width: 5em !global;
  width: $width;
}

#sidebar {
  width: $width;
}

编译为:

#main {
  width: 5em;
}

#sidebar {
  width: 5em;
}

由于历史原因,变量名称(和所有其他 Sass 标识符)可以互换使用连字符和下划线。 例如,如果定义了一个名为$main-width的变量,那么可以以$main_width的形式访问它,反之亦然。

数据类型

SassScript 支持八种数据类型:

  • 数字(例如 1.2, 13, 10px)
  • 有或者没有引号的文本字符串(例如 “foo”,“bar”,baz)
  • 颜色(例如 blue,#04a3f9,rgba(255,0,0,0.5) )
  • 布尔值(例如 true, false)
  • null(例如null)
  • 以空格或逗号分隔的值列表(例如 1.5em 1em 0 2em, Helvetica, Arial, sans-serif)
  • 从一个值映射到另一个值的 map(例如 (key1: value1, key2: value2))
  • 函数引用(function references)

SassScript 还支持所有其他类型的 CSS 属性值,如 Unicode 范围和!important声明。 但是,这些类型没有特殊处理。 它们被视为无引号的字符串。

字符串

CSS 指定两种字符串:带有引号的字符串,例如"Lucida Grande"'http://sass-lang.com',以及没有引号的字符串,如sans-serifbold。 SassScript 识别这两种类型,一般来说,如果在 Sass 文档中使用了一种字符串,那么在生成的 CSS 中将使用该类型的字符串。

但是,有一个例外:当使用#{}插值时,有引号的字符串将去除引。 这使得更容易使用例如 mixin 中的选择器名称。 例如:

@mixin firefox-message($selector) {
  body.firefox #{$selector}:before {
    content: "Hi, Firefox users!";
  }
}

@include firefox-message(".header");

编译为:

body.firefox .header:before {
  content: "Hi, Firefox users!"; }

列表

列表是 Sass 如何表示 CSS 声明诸如margin:10px 15px 0 0font-face:Helvetica,Arial,sans-serif的值。 列表只是一系列其他值,用空格或逗号分隔。 事实上,单个值也算作列表:它们只是一个条目的列表。

列表自身不会做太多,但是 SassScript 列表函数使它们变得有用。 nth函数可以访问列表中的条目,join函数可以连接多个列表到一起,并且append函数可以将条目添加到列表中。 @each指令还可以为列表中的每个条目添加样式。

除了包含简单的值之外,列表还可以包含其他列表。 例如,1px 2px, 5px 6px是包含列表1px 2px和列表5px 6px的两项列表。 如果内部列表与外部列表具有相同的分隔符,则需要使用括号来清晰标记内部列表的开始和结束。 例如,(1px 2px) (5px 6px)也是包含列表1px 2px和列表5px 6px的两项目列表。 区别在于外部列表是空格分隔的,之前是逗号分隔。

当列表变成纯 CSS 时,Sass 不会添加任何括号,因为 CSS 不了解它们。这意味着(1px 2px) (5px 6px)1px 2px 5px 6px将在它们变成 CSS 时看起来一样。但是,当它们是 Sass 时,它们是不一样的:第一个是包含两个列表的列表,而第二个是包含四个数字的列表。

列表也可以没有任何条目。这些列表用()(也是空的 map)表示。它们不能直接输出到 CSS;如果你尝试做诸如font-family: (),Sass 会引发错误。如果列表包含空列表或null值,如1px 2px () 3px1px 2px null 3px,则空列表和null值将在包含列表变为 CSS 之前被删除。

逗号分隔的列表可能有一个尾随逗号。这是特别有用的,因为它允许您表示单个元素列表。例如,(1,)是包含 1 的列表,(1 2 3,)是一个包含空格分隔的列表的逗号分隔的列表,其中包含 1, 2 和 3。

括号列表

列表也可以用方括号表示 - 我们称之为括号列表。 包含的括号列表在 CSS 网格布局中用作行名称,但也可以像任何其他列表一样在纯 Sass 代码中使用。 括号列表可以是逗号或空格分隔的。

Map

Map 表示键和值之间的关联,其中键用于查找值。它们可以轻松地将值收集到命名组中,并动态访问这些组。它们在 CSS 中没有直接的并行性,尽管它们在语法上类似于媒体查询表达式:

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

与列表不同,map 必须始终用括号括起来,并且必须始终以逗号分隔。Map 中的键和值都可以是任何 SassScript 对象。Map 可能只有一个与给定键相关联的值(尽管该值可能是一个列表)。但是,给定的值可能与许多键相关联。

像列表一样,map 大都使用 SassScript 函数进行操作。 map-get函数在 map 中查找值,map-merge函数将值添加到 map。 @each指令可用于为 map 中的每个键/值对添加样式。Map 中的对的顺序始终与创建 map 时的顺序相同。

Map 也可以随时随地向列表一样使用。当由列表函数使用时,map 将被视为成对的列表。例如,(key1: value1, key2: value2)可以像嵌套列表key1 value1, key2 value2由列表函数一样处理。除了空列表之外,列表不能被视为 map。()表示没有键/值对的 map 和没有元素的列表。

请注意,map 键可以是任何 Sass 数据类型(甚至是另一个 map),声明 map 的语法允许任意的 SassScript 表达式被计算来确定键。

Map 无法转换为纯 CSS。使用一个作为 CSS 函数的变量或参数的值将导致错误。使用inspect($value)函数来生成一个对调试 map 有用的输出字符串。

颜色

任何 CSS 颜色表达式返回 SassScript 颜色值。 这包括大量命名的颜色,与无引号的字符串不可区分。

在压缩输出模式下,Sass 将输出颜色的最小 CSS 表示。 例如,#FF0000将以压缩模式输出为红色,但blanchedalmond将输出为#FFEBCD

用户遇到的命名颜色的常见问题是,由于 Sass 喜欢与其他输出模式中输入的输出格式相同的输出格式,所以当压缩时插入到选择器中的颜色将变为无效语法。 为了避免这种情况,如果它们是用于构建选择器的话,总是引用命名的颜色。

第一类函数

函数引用由get-function($function-name)返回。 该函数可以传递给call($function, $args...),它引用的函数将被调用。 第一类函数不能直接用作 CSS 输出,任何尝试都会导致错误。

运算符

所有类型都支持等式运算(==!=)。 此外,每种类型都有其特殊支持的运算符。

数字操作符

SassScript 支持对数字(加法+,减法-,乘法*,除法/和模数)的标准算术运算。 算术运算时,Sass 数学函数保留单位。 这意味着,就像在现实生活中一样,你不能使用不兼容单位的数字(例如添加一个带有pxem的数字)和两个相乘的数字相乘的数字将产生平方单位(10px * 10px == 100px * px)。 请注意px * px是一个无效的 CSS 单位,试图在 CSS 中使用无效单位您会收到 Sass 的错误。

数字也支持关系运算符(<><=>=),所有类型都支持等式运算符(==!=)。

除法和 /

CSS 允许/显示在属性值中作为分隔数字的一种方式。 由于 SassScript 是 CSS 属性语法的扩展,它必须支持这一点,同时也允许/用于除法。 这意味着默认情况下,如果两个数字在 SassScript 中被/分开,则它们将以这种方式出现在生成的 CSS 中。

但是,有三种情况将/解释为除法。 这些涵盖绝大多数实际使用除法的情况。 他们是:

  1. 如果值或其任何部分存储在变量中或由函数返回。
  2. 如果值由括号括起来,除非这些括号在列表外面,而且值在里面。
  3. 如果该值用作另一个算术表达式的一部分。

例如:

p {
  font: 10px/8px;             // Plain CSS, no division
  $width: 1000px;
  width: $width/2;            // Uses a variable, does division
  width: round(1.5)/2;        // Uses a function, does division
  height: (500px/2);          // Uses parentheses, does division
  margin-left: 5px + 8px/2px; // Uses +, does division
  font: (italic bold 10px/8px); // In a list, parentheses don't count
}

编译为:

p {
  font: 10px/8px;
  width: 500px;
  height: 250px;
  margin-left: 9px; }

如果你想连同纯 CSS /一起使用变量,可以使用#{}来插入它们。 例如:

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

编译为:

p {
  font: 12px/30px; }

减法,负数和-

-在 CSS 和 Sass 中有许多不同的意义。 它可以是一个减法运算符(如5px - 3px),负数的开头(如-3px),一元否定运算符(如-$var)或标识符的一部分(如font-weight)。 大多数时候,很清楚哪个是哪个,但有一些棘手的例子。 作为一般规则,如下您最安全:

  • 当减法时,您总是在-两边包含空格。
  • -之前包含一个空格,但不包括负数或一次否定符之后。
  • 如果在一个空格分隔的列表中,包括的一元否定符在圆括号中,就像在10px (-$var)中一样。

不同含义的-在以下顺序中的优先级:

  1. - 作为标识符的一部分。 这意味着a-1是一个值为“a-1”的无引号字符串。 唯一的例外是单位; Sass 通常允许使用任何有效的标识符作为标识符,但标识符可能不包含连字符后跟数字。 这意味着5px-3px5px - 3px相同。

  2. 没有空格的两个数字之间的-。 这表示减法,所以1-21 - 2相同。

  3. 在字面数字的开头的-。 这表示一个负数,所以1 -2是一个包含1-2的列表。

  4. 两个数字之间的-,无论空白。 这表示减法,所以1 -$var1 - $var相同。

  5. 在一个值之前的-。 这表明一元否定运算符; 也就是说,运算符需要一个数字并返回其负数。

颜色运算符

颜色值支持所有算术运算,它们分段工作。 这意味着运算依次在红色,绿色和蓝色部分上执行。 例如:

p {
  color: #010203 + #040506;
}

计算01 + 04 = 0502 + 05 = 0703 + 06 = 09,并编译为:

p {
  color: #050709; }

通常,使用颜色函数比尝试使用颜色算术来实现相同的效果更有用。

算术运算也可以在数字和颜色之间工作,也是分段的。 例如:

p {
  color: #010203 * 2;
}

计算01 * 2 = 0202 * 2 = 0403 * 2 = 06,并编译为:

p {
  color: #020406; }

请注意,使用 alpha 通道的颜色(使用 rgbahsla 函数创建的颜色)必须具有相同的 alpha 值,以便与其一起完成颜色算术。 算术不影响 alpha 值。 例如:

p {
  color: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75);
}

编译为:

p {
  color: rgba(255, 255, 0, 0.75); }

可以使用opacifytransparentize函数调整颜色的 alpha 通道。 例如:

$translucent-red: rgba(255, 0, 0, 0.5);
p {
  color: opacify($translucent-red, 0.3);
  background-color: transparentize($translucent-red, 0.25);
}

编译为:

p {
  color: rgba(255, 0, 0, 0.8);
  background-color: rgba(255, 0, 0, 0.25); }

IE 过滤器要求所有颜色包括 alpha 层,并且格式严格为 #AABBCCDD。 您可以使用ie_hex_str函数更容易地转换颜色。 例如:

$translucent-red: rgba(255, 0, 0, 0.5);
$green: #00ff00;
div {
  filter: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr='#{ie-hex-str($green)}', endColorstr='#{ie-hex-str($translucent-red)}');
}

编译为:

div {
  filter: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr=#FF00FF00, endColorstr=#80FF0000);
}

字符串运算符

+运算符可用于连接字符串:

p {
  cursor: e + -resize;
}

编译为:

p {
  cursor: e-resize; }

请注意,如果将有引号的字符串添加到没有引号的字符串(即,带引号的字符串在+的左侧),则结果是有引号的字符串。 同样,如果一个没有引号的字符串被添加到有引号的字符串(没有引号的字符串在+的左边),结果是一个无引号的字符串。 例如:

p:before {
  content: "Foo " + Bar;
  font-family: sans- + "serif";
}

编译为:

p:before {
  content: "Foo Bar";
  font-family: sans-serif; }

默认情况下,如果两个值彼此相邻放置,则它们将与空格相连:

p {
  margin: 3px + 4px auto;
}

编译为:

p {
  margin: 7px auto; }

在一串文本中,#{}样式插值可用于在字符串中放置动态值:

p:before {
  content: "I ate #{5 + 10} pies!";
}

编译为:

p:before {
  content: "I ate 15 pies!"; }

空值(null)被视为用于字符串插值的空字符串:

$value: null;
p:before {
  content: "I ate #{$value} pies!";
}

编译为:

p:before {
  content: "I ate  pies!"; }

布尔运算符

SassScript 支持布尔值的andornot运算符。

列表运算符

列表不支持任何特殊运算符。 而是使用列表函数进行操作。

括号

括号可用于影响运算顺序:

p {
  width: 1em + (2em * 3);
}

编译为:

p {
  width: 7em; }

函数

SassScript 定义了一些使用常规 CSS 函数语法调用的有用函数:

p {
  color: hsl(0, 100%, 50%);
}

编译为:

p {
  color: #ff0000; }

有关可用函数的完整列表,请参阅此页面

关键字参数

也可以使用显式关键字参数调用 Sass 函数。 上面的例子也可以写成:

p {
  color: hsl($hue: 0, $saturation: 100%, $lightness: 50%);
}

虽然这不太简洁,它可以使样式表更容易阅读。 它还允许函数呈现更灵活的接口,提供许多参数,而不会变得难以调用。

可以以任何顺序传递命名的参数,并且可以省略具有默认值的参数。 由于命名参数是变量名,下划线和破折号可以互换使用。

有关 Sass 函数及其参数名称的完整列表,以及有关在 Ruby 中定义自己的说明,请参见Sass::Script::Functions

插值:#{}

您还可以使用#{}插值语法在选择器和属性名称中使用 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; }

SassScript 中的 &

就像在选择器中使用的一样,SassScript 中的&指的是当前的父选择器。 它是以逗号分隔的空格分隔列表。 例如:

.foo.bar .baz.bang, .bip.qux {
  $selector: &;
}

$selector的值现在是((".foo.bar" ".baz.bang"), ".bip.qux")。 这里复合选择器引号引起来以指明它们是字符串,但实际上它们是没用引号的。 即使父选择器不包含逗号或空格,&将始终具有两个级别的嵌套,因此可以一致地进行访问。

如果没有父选择器,则的值将为null。 这意味着您可以在mixin中使用它来检测父选择器是否存在:

@mixin does-parent-exist {
  @if & {
    &:hover {
      color: red;
    }
  } @else {
    a {
      color: red;
    }
  }
}

变量的默认值:!default

你可以赋值给变量,这些变量如果尚未通过将!default标志添加到值的末尾来赋值。 这意味着如果变量已被赋值,它将不会被重新赋值,但是如果没有值,它将被赋予一个值。

例如:

$content: "First content";
$content: "Second content?" !default;
$new_content: "First time reference" !default;

#main {
  content: $content;
  new-content: $new_content;
}

编译为:

#main {
  content: "First content";
  new-content: "First time reference"; }

具有null值的变量被视为未被!default赋值:

#main {
  content: "First content";
  new-content: "First time reference"; }

Variables with null values are treated as unassigned by !default:

$content: null;
$content: "Non-null content" !default;

#main {
  content: $content;
}

编译为:

#main {
  content: "Non-null content"; }

@-Rules 和指令

Sass 支持所有 CSS3 @-rules,以及一些被称为「指令」的额外的 Sass-specific。 这些在 Sass 中有各种各样的效果,详见下文。 另请参阅控制指令和mixin指令。

@import

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

Sass 在当前目录中查找其他 Sass 文件,在 Rack,Rails 或 Merb 下查找 Sass 文件目录。可以使用:load_paths选项或命令行中的--load-path选项指定其他搜索目录。

@import需要一个文件名才能导入。默认情况下,它搜索一个 Sass 文件以直接导入,但有下面几种情况可以将其编译为 CSS @import规则:

  • 如果文件的扩展名是.css
  • 如果文件名以http//开头。
  • 如果文件名是url()
  • 如果@import有任何媒体查询。

如果没有满足上述条件,并且扩展名为.scss.sass,则将导入命名的 Sass 或 SCSS 文件。如果没有扩展名,Sass 将尝试找到具有该名称和.scss.sass扩展名的文件并将其导入。

例如:

@import "foo.scss";

@import "foo";

都将导入文件foo.scss,而

@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo);

将全部编译成

@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo);

也可以在一个@import中导入多个文件。 例如:

@import "rounded-corners", "text-shadow";

将导入rounded-cornerstext-shadow文件。

导入可能包含#{}插值,但只能有一定的限制。 不可能基于变量动态导入 Sass 文件; 插值仅适用于 CSS 导入。 因此,它仅适用于url()导入。 例如:

$family: unquote("Droid+Sans");
@import url("http://fonts.googleapis.com/css?family=#{$family}");

将编译到

@import url("http://fonts.googleapis.com/css?family=Droid+Sans");

Partials

如果您有要导入但不想编译到 CSS 文件的 SCSS 或 Sass 文件,则可以在文件名的开头添加下划线。 这将告诉 Sass 不要把它编译成一个普通的 CSS 文件。 然后,您可以导入这些文件而不使用下划线。

例如,你可能有_colors.scss。 然后不会创建_colors.css文件,你可以做

@import "colors";

_colors.scss将被导入。

请注意,在同一目录中您可能不会包含具有相同名称的部分(partial)和全部(non-partial)。 例如,_colors.scss可能不存在color.scss旁边。

嵌套 @import

虽然大部分时间只是将@import放在文档的顶层最有用,但是可以将它们包含在 CSS 规则和@media规则中。 像基本的@import一样,这包括@import完成的文件的内容。 但是,导入的规则将嵌套在原始@import的相同位置。

例如,如果example.scss包含

.example {
  color: red;
}

然后

#main {
  @import "example";
}

将编译到

#main .example {
  color: red;
}

只允许在文档的基本级别(如@mixin@charset)的指令不允许在@import入的文件的嵌套上下文中使用。

在 mixin 或控制指令中嵌套@import是不可能的。

@media

Sass 中的@media指令的行为就像在纯 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; } }

@media查询也可以嵌套在一起。 然后使用and运算符组合查询。 例如:

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

编译为:

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

最后,@media查询可以包含 SassScript 表达式(包括变量,函数和运算符)来代替特征名称和特征值。 例如:

$media: screen;
$feature: -webkit-min-device-pixel-ratio;
$value: 1.5;

@media #{$media} and ($feature: $value) {
  .sidebar {
    width: 500px;
  }
}

编译为:

@media screen and (-webkit-min-device-pixel-ratio: 1.5) {
  .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;
}

不幸的是,这意味着我们必须永远记得和.seriousError一起使用.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;
}

这意味着除了.seriousError特有的样式之外,为.error定义的所有样式也适用于.seriousError。 实际上,类.seriousError的每个元素也都有.error类。

使用.error的其他规则也适用于.seriousError。 例如,如果我们对黑客造成的错误有特殊的风格:

.error.intrusion {
  background-image: url("/image/hacked.png");
}

然后,<div class =“seriousError intrusion”>也将具有hacked.png背景图像。

他是如何工作的

@extend通过在扩展选择器(例如 .error)出现的样式表中的任何位置插入扩展选择器(例如 .seriousError)。 所以上面的例子:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.error.intrusion {
  background-image: url("/image/hacked.png");
}
.seriousError {
  @extend .error;
  border-width: 3px;
}

编译为:

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

.error.intrusion, .seriousError.intrusion {
  background-image: url("/image/hacked.png"); }

.seriousError {
  border-width: 3px; }

当合并选择器时,@extend足够聪明以避免不必要的重复,所以像.seriousError.seriousError这样的东西被转换成.seriousError。 另外,它不会产生不能匹配任何东西的选择器,如#main#footer

扩展复合选择器

类选择器不是唯一可以扩展的选项。 可以扩展任何仅涉及单个元素的选择器,例如.special.coola:hovera.user[href^=“http//”]。 例如:

.hoverlink {
  @extend a:hover;
}

就像类一样,这意味着为a:hover定义的所有样式也应用于.hoverlink。 例如:

.hoverlink {
  @extend a:hover;
}
a:hover {
  text-decoration: underline;
}

编译为:

a:hover, .hoverlink {
  text-decoration: underline; }

就像上面的.error.intrusion一样,使用a:hover的任何规则也可以用于.hoverlink,即使它们还有其他选择器。 例如:

.hoverlink {
  @extend a:hover;
}
.comment a.user:hover {
  font-weight: bold;
}

编译为:

.comment a.user:hover, .comment .user.hoverlink {
  font-weight: bold; }

多个扩展

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

.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; }

实际上,具有类.seriousError的每个元素也都有类.error.attention。 因此,文档中稍后定义的样式优先:.seriousError具有背景颜色#ff0而不是#fdd,因为.attention的定义晚于.error

多个扩展也可以使用逗号分隔的选择器列表来书写。 例如,@extend .error,.attention@extend .error; @extend .attention相同。

链扩展

一个选择器可以扩展另一个选择器,而另一个选择器又扩展了第三个。 例如:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}
.criticalError {
  @extend .seriousError;
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%;
}

现在具有类.seriousError的每个元素一样也有类.error,所有具有类.criticalError都有类.seriousError.error。 它编译为:

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

.seriousError, .criticalError {
  border-width: 3px; }

.criticalError {
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%; }

选择器序列

选择器序列,诸如.foo .bar.foo + .bar,目前无法扩展。 但是,嵌套选择器本身可以使用@extend。 例如:

#fake-links .link {
  @extend a;
}

a {
  color: blue;
  &:hover {
    text-decoration: underline;
  }
}

编译为:

a, #fake-links .link {
  color: blue; }
  a:hover, #fake-links .link:hover {
    text-decoration: underline; }

合并选择器序列

有时选择器序列扩展在另一个序列中出现的另一个选择器。 在这种情况下,需要合并两个序列。 例如:

#admin .tabbar a {
  font-weight: bold;
}
#demo .overview .fakelink {
  @extend a;
}

虽然在技术上可以生成可能匹配任一序列的所有选择器,但这将使样式表太大。 例如,上面的简单示例将需要十个选择器。 相反,Sass 只生成可能有用的选择器。

当合并的两个序列没有共同的选择符时,则生成两个新的选择器:具有第一序列的一个在第二个序列之前,并且具有第二个序略的一个在第一个序列之前。 例如:

#admin .tabbar a {
  font-weight: bold;
}
#demo .overview .fakelink {
  @extend a;
}

编译为:

#admin .tabbar a,
#admin .tabbar #demo .overview .fakelink,
#demo .overview #admin .tabbar .fakelink {
  font-weight: bold; }

如果两个序列确实共享一些选择器,则这些选择器将被合并在一起,并且只有差异(如果还存在)将交替。 在这个例子中,这两个序列都包含 id #admin,所以生成的选择器会合并这两个 id:

#admin .tabbar a {
  font-weight: bold;
}
#admin .overview .fakelink {
  @extend a;
}

这编译成:

#admin .tabbar a,
#admin .tabbar .overview .fakelink,
#admin .overview .tabbar .fakelink {
  font-weight: bold; }

@extend-Only 选择器

有时你会写一个只需要@extend的类的样式,而不是直接在你的 HTML 中使用。 在编写 Sass 库时尤其如此,如果需要,可以为用户提供样式到@extend,如果不需要,则忽略它们。

如果您为此使用普通类,则在生成样式表时最终会创建大量额外的 CSS,并且会遇到与 HTML 中正在使用的其他类相冲突的风险。 这就是为什么 Sass 支持「占位符选择器」(例如,%foo)。

占位符选择器看起来像类(class)和 id 选择器,除了用%代替#.。 它们可以在类(class)或者 id 的任何地方使用,而且自己也可以防止将规则集渲染到 CSS。 例如:

// This ruleset won't be rendered on its own.
#context a%extreme {
  color: blue;
  font-weight: bold;
  font-size: 2em;
}

但是,占位符选择器可以扩展,就像类(class)和 id 一样。 扩展选择器将生成,但基本占位符选择器不会生成。 例如:

.notice {
  @extend %extreme;
}

编译为:

#context a.notice {
  color: blue;
  font-weight: bold;
  font-size: 2em; }

!optional 标志

通常当你扩展一个选择器时,如果@extend不起作用,这是一个错误。 例如,如果你写了a.important {@extend .notice},如果没有包含.notice的选择器,这是一个错误。 如果包含.notice的唯一选择器是h1.notice也是一个错误,因为h1a冲突,因此不会生成新的选择器。

有时候,您希望允许@extend不生成任何新的选择器。 为此,只需在选择器之后添加!optional标志。 例如:

a.important {
  @extend .notice !optional;
}

指令中的 @extend

在诸如@media等指令中使用@extend有一些限制。 Sass 无法使@media块之外的 CSS 规则应用于其中的选择器,而不会通过在所有位置复制样式来创建大量的样式表。 这意味着如果在@media(或其他 CSS 指令)中使用@extend,则只能扩展出在相同指令块中的选择器。

例如,以下工作正常:

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

但这是一个错误:

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

@media print {
  .seriousError {
    // INVALID EXTEND: .error is used outside of the "@media print" directive
    @extend .error;
    border-width: 3px;
  }
}

有一天,我们希望在浏览器中本地支持@extend,这将允许它在@media和其他指令中使用。

@at-root

@at-root指令会导致一个或多个规则在文档的根目录下发布,而不是嵌套在其父选择器的下面。 它可以与单个内联选择器一起使用:

.parent {
  ...
  @at-root .child { ... }
}

这会产生:

.parent { ... }
.child { ... }

或者它可以与包含多个选择器的块一起使用:

.parent {
  ...
  @at-root {
    .child1 { ... }
    .child2 { ... }
  }
  .step-child { ... }
}

这将输出以下内容:

.parent { ... }
.child1 { ... }
.child2 { ... }
.parent .step-child { ... }

@at-root (without: ...)@at-root (with: ...)

默认情况下,@at-root仅排除选择器。 但是,也可以使用@at-root来移动到嵌套伪指令(例如@media)之外。 例如:

@media print {
  .page {
    width: 8in;
    @at-root (without: media) {
      color: red;
    }
  }
}

产生:

@media print {
  .page {
    width: 8in;
  }
}
.page {
  color: red;
}

您可以使用@at-root (without: ...)移动到任何指令之外。 您还可以使用由空格分隔的多个指令来执行此操作:@at-root (without: media supports)可以移动到@media@supports查询之外。

有两个特殊的值可以传递给@at-root。 「规则」是指正常的 CSS 规则; @at-root (without: rule)与没有查询的@at-root相同。 @at-root (without: all)意味着样式应该移到*所有(all)*指令和 CSS 规则之外。

如果要指定要包括哪些指令或规则,而不是列出应排除哪些指令或规则,则可以使用with代替without。 例如,@at-root (with: rule)将移动到所有指令之外,但将保留任何 CSS 规则。

@debug

@debug指令将 SassScript 表达式的值打印到标准错误输出流。 它有助于调试 SassScript 复杂的 Sass 文件。 例如:

@debug 10em + 12em;

输出:

Line 1 DEBUG: 22em

@warn

@warn指令将 SassScript 表达式的值打印到标准错误输出流。 对于需要警告用户弃用或从次要 mixin 使用错误中恢复的库很有用。 @warn@debug有两个主要区别:

  1. 您可以使用--quiet命令行选项或:quiet Sass 选项关闭警告。
  2. 将与消息一起打印样式表跟踪,以便被警告的用户可以看到他们的样式导致警告的位置。

用法示例:

@mixin adjust-location($x, $y) {
  @if unitless($x) {
    @warn "Assuming #{$x} to be in pixels";
    $x: 1px * $x;
  }
  @if unitless($y) {
    @warn "Assuming #{$y} to be in pixels";
    $y: 1px * $y;
  }
  position: relative; left: $x; top: $y;
}

@error

@error指令将 SassScript 表达式的值抛出一个致命的错误,包括一个很好的堆栈跟踪。 它用于验证 mixin 和函数的参数。 例如:

@mixin adjust-location($x, $y) {
  @if unitless($x) {
    @error "$x may not be unitless, was #{$x}.";
  }
  @if unitless($y) {
    @error "$y may not be unitless, was #{$y}.";
  }
  position: relative; left: $x; top: $y;
}

目前没有办法捕捉错误。

控制指令和表达式

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

**注意:**控制指令是高级功能,在日常样式中不常见。 它们主要用于 mixin,特别是那些类似 Compass 库的一部分,因此需要很大的灵活性。

if()

内置的if()函数允许您在条件上分支,并且只返回两种可能的结果之一。 它可以在任何脚本上下文中使用。 if函数仅评估与其返回的参数相对应的参数 - 这允许您引用可能未定义的变量,或者计算否则会导致错误(例如,除以零)。

if(true, 1px, 2px) => 1px
if(false, 1px, 2px) => 2px

@if

@if指令采用 SassScript 表达式,如果表达式返回除falsenull之外的任何值,则使用嵌套在其下的样式:

p {
  @if 1 + 1 == 2 { border: 1px solid;  }
  @if 5 < 3      { border: 2px dotted; }
  @if null       { border: 3px double; }
}

编译为:

p {
  border: 1px solid; }

如果要区分$var == false$var == null,您可以显式地测试这些。

@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>。 请注意关键字throughto的不同。 $var可以是任何变量名,如$i; <start><end>是应该返回整数的 SassScript 表达式。 当<start>大于<end>时,计数器将递减而不是递增。

@for语句设置$var为指定范围内的每个连续的数字,并且每次使用$var的值输出嵌套样式。 对于from ... through的形式,范围包括<start><end>的值,但是from ... to的形式运行到但不包括<end>的值。 使用through语法,

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

编译为:

.item-1 {
  width: 2em; }
.item-2 {
  width: 4em; }
.item-3 {
  width: 6em; }

@each

@each指令通常有@each $var in <list or map>的形式。 $var可以是任何变量名称,如$length$name,而<list or map>是返回列表或 map 的 SassScript 表达式。

@each规则设置$var为列表或 map 中的每个条目,然后使用$var的值输出其包含的样式。 例如:

@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指令也可以使用多个变量,如@each $var1,$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; }

由于 map 被视为成对的列表,因此与它们一起进行多次赋值。 例如:

@each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
  #{$header} {
    font-size: $size;
  }
}

编译为:

h1 {
  font-size: 2em; }
h2 {
  font-size: 1.5em; }
h3 {
  font-size: 1.2em; }

@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; }

Mixin 指令

Mixin 允许您定义可以在整个样式表中重新使用的样式,而无需借助于非语义类,如.float-left。 Mixin 还可以包含完整的 CSS 规则,还有其他在 Sass 文档中允许的内容。 他们甚至可以携带参数,让您可以用很少的 mixin 生产各种风格。

定义 Mixin: @mixin

Mixin 用@mixin指令定义。 之后是 mixin 的名称,可选的参数,以及包含 mixin 内容的块。 例如,large-text mixin 定义如下:

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

Mixin 还可能包含与属性混合的选择器。 选择器甚至可以包含父引用(parent references)。 例如:

@mixin clearfix {
  display: inline-block;
  &:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
  }
  * html & { height: 1px }
}

由于历史原因,mixin 名称(和所有其他 Sass 标识符)可以互换使用连字符和下划线。 例如,如果您定义了一个名为add-column的 mixin,那么可以将其作为add_column包含,反之亦然。

包含 Mixin: @include

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

.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; }

Mixin 定义也可以包括其他 mixin。 例如:

@mixin compound {
  @include highlighted-background;
  @include header-text;
}

@mixin highlighted-background { background-color: #fc0; }
@mixin header-text { font-size: 20px; }

Mixin 可以包括它们自身。 这与 3.3 之前的 Sass 版本的行为不同,其中禁止了 mixin 递归。

仅限定义后代选择器的 mixin 可以安全地混合到文档的最顶层。

参数

当给出的参数包含 mixin 且使 mixin 作为变量可用时,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 还可以使用正常的变量设置语法为其参数指定默认值。 然后,当包含 mixin 时,如果它不传递该参数,将使用默认值。 例如:

@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。 例如,上面的例子可以写成:

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

虽然这不太简洁,它可以使样式表更容易阅读。 它还允许函数呈现更灵活的接口,提供许多参数,而不会变得难以调用。

可以以任何顺序传递命名的参数,并且可以省略具有默认值的参数。 由于命名参数是变量名,下划线和破折号可以互换使用。

尾随逗号

当 mixin 或函数的最后一个参数是位置或关键字样式的参数时,该参数后面可以跟随一个逗号。 有些更喜欢这种编码风格,因为它可以导致更简洁的差异和更少的语法错误重构时。

可变参数

有时候,混合或函数可以获取未知数量的参数。 例如,用于创建框阴影的mixin可能需要任意数量的阴影作为参数。 对于这些情况,Sass支持“变量参数”,它们是mixin或函数声明的结尾的参数,它将所有剩余参数作为列表进行打包。 这些参数看起来就像正常的参数,但是后跟….例如:

@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;
}

变量参数还包含传递给mixin或函数的任何关键字参数。 这些可以使用关键字($ args)函数访问,它们将它们作为地图从字符串(不含$)返回到值。

调用mixin时也可以使用变量参数。 使用相同的语法,您可以展开一个值列表,以便每个值作为单独的参数传递,或者展开值的映射,以使每个对被视为关键字参数。 例如:

@mixin colors($text, $background, $border) {
  color: $text;
  background-color: $background;
  border-color: $border;
}

$values: #ff0000, #00ff00, #0000ff;
.primary {
  @include colors($values...);
}

$value-map: (text: #00ff00, background: #0000ff, border: #ff0000);
.secondary {
  @include colors($value-map...);
}

编译为:

.primary {
  color: #ff0000;
  background-color: #00ff00;
  border-color: #0000ff;
}

.secondary {
  color: #00ff00;
  background-color: #0000ff;
  border-color: #ff0000;
}

只要列表出现在地图之前,您可以传递参数列表和地图,如@include颜色($ values …,$ map …)。

您可以使用变量参数来包装mixin并添加其他样式,而无需更改mixin的参数签名。 如果这样做,关键字参数将直接传递到包装的mixin。 例如:

@mixin wrapped-stylish-mixin($args...) {
  font-weight: bold;
  @include stylish-mixin($args...);
}

.stylish {
  // The $width argument will get passed on to "stylish-mixin" as a keyword
  @include wrapped-stylish-mixin(#00ff00, $width: 100px);
}

传递内容块到 Mixin

可以将一组样式传递给 mixin,以便在 mixin 包含的样式中进行放置。 样式将出现在 mixin 中找到的任何@content指令的位置。 这使得可以定义与选择器和指令的构造有关的抽象。

例如:

@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简写语法完成:

=apply-to-ie6-only
  * html
    @content

+apply-to-ie6-only
  #logo
    background-image: url(/logo.gif)

**注意:**当@content指令被多次指定或在循环中时,样式块将与每个调用重复。

某些 mixin 可能需要传递的内容块,或者可能具有取决于是否传递内容块的不同的行为。 当内容块传递到当前 mixin 并且可以用于实现这样的行为时,content-exists()函数将返回 true。

可变范围和内容块

传递给 mixin 的内容块在块被定义的范围内计算,而不在 mixin 范围内。 这意味着在传递的样式块中无法使用 mixin 的本地变量,变量将解析为全局值:

$color: white;
@mixin colors($color: blue) {
  background-color: $color;
  @content;
  border-color: $color;
}
.colors {
  @include colors { color: $color; }
}

编译为:

.colors {
  background-color: blue;
  color: white;
  border-color: blue;
}

此外,这使得清楚的是,传递块中使用的变量和 mixin 与其中定义块的其他样式相关。 例如:

#sidebar {
  $sidebar-width: 300px;
  width: $sidebar-width;
  @include smartphone {
    width: $sidebar-width / 3;
  }
}

函数指令

可以在 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 或 CSS 的一部分。 例如,如果您为 ACME Corp 工作,则可能在-acme-grid-width之上命名函数。

用户定义的函数也支持与 mixin 相同方式的可变参数。

由于历史原因,函数名称(和所有其他 Sass 标识符)可以互换使用连字符和下划线。 例如,如果定义了一个名为grid-width的函数,可以将其用作grid_width,反之亦然。

输出样式

虽然 Sass 输出的默认 CSS 样式非常好,反映了文档的结构,但是味道和需求也各不相同,所以 Sass 支持其他几种样式。

Sass 允许您通过设置:style选项或使用--style命令行标志来选择四种不同的输出样式。

:nested

嵌套样式是默认的 Sass 样式,因为它反映了 CSS 样式的结构和他们所设计的 HTML 文档。 每个属性都有自己的行,但缩进不是常量。 根据嵌套的深度,每个规则都是缩进的。 例如:

#main {
  color: #fff;
  background-color: #000; }
  #main p {
    width: 10em; }

.huge {
  font-size: 10em;
  font-weight: bold;
  text-decoration: underline; }

嵌套样式在查看大型 CSS 文件时非常有用:它可以让您轻松掌握文件的结构,而无需实际读取任何内容。

:expanded

扩展是一个更典型的人造 CSS 风格,每个属性和规则占一线。 属性在规则中缩进,但是规则不以任何特殊方式缩进。 例如:

#main {
  color: #fff;
  background-color: #000;
}
#main p {
  width: 10em;
}

.huge {
  font-size: 10em;
  font-weight: bold;
  text-decoration: underline;
}

:compact

紧凑型样式采用比嵌套或扩展更少的空间。 它还将重点放在选择器上而不是他们的属性。 每个 CSS 规则仅占用一行,每行都在该行上定义。 嵌套规则彼此相邻,没有换行符,而单独的规则组在它们之间具有换行符。 例如:

#main { color: #fff; background-color: #000; }
#main p { width: 10em; }

.huge { font-size: 10em; font-weight: bold; text-decoration: underline; }

:compressed

压缩样式占用尽可能少的空间,除了分隔选择器和文件末尾的换行符之外,没有空白。 它还包括一些其他轻微的压缩,例如选择最小的颜色表示。 这并不意味着人的可读性。 例如:

#main{color:#fff;background-color:#000}#main p{width:10em}.huge{font-size:10em;font-weight:bold;text-decoration:underline}

参考

  1. Sass
  2. Sass documentation
  3. Sass in GitHub
  4. SASS用法指南