Sass 参考
什么是 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-family
,font-size
和font-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-serif
或 bold
。 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 0
或font-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 () 3px
或1px 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 数学函数保留单位。 这意味着,就像在现实生活中一样,你不能使用不兼容单位的数字(例如添加一个带有px
和em
的数字)和两个相乘的数字相乘的数字将产生平方单位(10px * 10px == 100px * px
)。 请注意,px * px
是一个无效的 CSS 单位,试图在 CSS 中使用无效单位您会收到 Sass 的错误。
数字也支持关系运算符(<
,>
,<=
,>=
),所有类型都支持等式运算符(==
,!=
)。
除法和 /
CSS 允许/
显示在属性值中作为分隔数字的一种方式。 由于 SassScript 是 CSS 属性语法的扩展,它必须支持这一点,同时也允许/
用于除法。 这意味着默认情况下,如果两个数字在 SassScript 中被/
分开,则它们将以这种方式出现在生成的 CSS 中。
但是,有三种情况将/
解释为除法。 这些涵盖绝大多数实际使用除法的情况。 他们是:
- 如果值或其任何部分存储在变量中或由函数返回。
- 如果值由括号括起来,除非这些括号在列表外面,而且值在里面。
- 如果该值用作另一个算术表达式的一部分。
例如:
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)
中一样。
不同含义的-
在以下顺序中的优先级:
-
-
作为标识符的一部分。 这意味着a-1
是一个值为“a-1”
的无引号字符串。 唯一的例外是单位; Sass 通常允许使用任何有效的标识符作为标识符,但标识符可能不包含连字符后跟数字。 这意味着5px-3px
与5px - 3px
相同。 -
没有空格的两个数字之间的
-
。 这表示减法,所以1-2
与1 - 2
相同。 -
在字面数字的开头的
-
。 这表示一个负数,所以1 -2
是一个包含1
和-2
的列表。 -
两个数字之间的
-
,无论空白。 这表示减法,所以1 -$var
与1 - $var
相同。 -
在一个值之前的
-
。 这表明一元否定运算符; 也就是说,运算符需要一个数字并返回其负数。
颜色运算符
颜色值支持所有算术运算,它们分段工作。 这意味着运算依次在红色,绿色和蓝色部分上执行。 例如:
p {
color: #010203 + #040506;
}
计算01 + 04 = 05
,02 + 05 = 07
和03 + 06 = 09
,并编译为:
p {
color: #050709; }
通常,使用颜色函数比尝试使用颜色算术来实现相同的效果更有用。
算术运算也可以在数字和颜色之间工作,也是分段的。 例如:
p {
color: #010203 * 2;
}
计算01 * 2 = 02
,02 * 2 = 04
和03 * 2 = 06
,并编译为:
p {
color: #020406; }
请注意,使用 alpha 通道的颜色(使用 rgba
或 hsla
函数创建的颜色)必须具有相同的 alpha 值,以便与其一起完成颜色算术。 算术不影响 alpha 值。 例如:
p {
color: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75);
}
编译为:
p {
color: rgba(255, 255, 0, 0.75); }
可以使用opacify
和transparentize
函数调整颜色的 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 支持布尔值的and
、or
和not
运算符。
列表运算符
列表不支持任何特殊运算符。 而是使用列表函数进行操作。
括号
括号可用于影响运算顺序:
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-corners
和text-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.cool
,a:hover
或a.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
也是一个错误,因为h1
与a
冲突,因此不会生成新的选择器。
有时候,您希望允许@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
有两个主要区别:
- 您可以使用
--quiet
命令行选项或:quiet
Sass 选项关闭警告。 - 将与消息一起打印样式表跟踪,以便被警告的用户可以看到他们的样式导致警告的位置。
用法示例:
@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 表达式,如果表达式返回除false
或null
之外的任何值,则使用嵌套在其下的样式:
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>
。 请注意关键字through
和to
的不同。 $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}