SassScript
除了普通的CSS属性的语法,Sass 支持一些扩展,名为SassScript。SassScript允许属性使用变量,算术和额外功能。SassScript可以在任何属性值被使用。
SassScript也可以用来生成选择器和属性名称,当编写mixins时非常有用。这是通过 interpolation(插值) 完成。
交互式 shell(Interactive Shell)
Interactive Shell 可以在命令行中测试 SassScript 的功能。在命令行中输入 sass -i,然后输入想要测试的 SassScript 查看输出结果:
您可以使用交互式shell(Interactive Shell)轻松地尝试 SassScript。
要箱运行启动 shell ,只要使用-i
选项的 sass 命令行(注:在命令行中输入 sass -i
)。
在提示符下,输入任何合法的 SassScript表达式,由它他评估并打印出您的结果:
$ sass -i
>> "Hello, Sassy World!"
"Hello, Sassy World!"
>> 1px + 1px + 1px
3px
>> #777 + #777
#eeeeee
>> #777 + #888
white
变量: $
(Variables: $
)
使用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
访问它,反之亦然。
数据类型 (Data Types)
SassScript 支持 7 种主要的数据类型:
- 数字 (例如:
1.2
,13
,10px
) - 文本字符串,带引号字符串和不带引号字符串(例如:
"foo"
,'bar'
,baz
) - 颜色 (例如:
blue
,#04a3f9
,rgba(255, 0, 0, 0.5)
) - 布尔值 (例如:
true
,false
) - 空值 (例如:
null
) - 值列表 (list),用空格或逗号分隔 (例如:
1.5em 1em 0 2em
,Helvetica, Arial, sans-serif
) - maps ,从一个值映射到另一个 (例如:
(key1: value1, key2: value2)
)
SassScript也支持其他所有类型的CSS属性值,比如 Unicode 字符集,或 !important
声明。然而,不会对这些类型的属性值做特殊处理,一律视为不带引号的字符串。
字符串(Strings)
CSS指定两种字符串类型:带引号的字符串(注:包括双引号和单引号),如"Lucida Grande"
或者 'http://sass-lang.com'
,还有不带引号的字符串,如sans-serif
或者 bold
。SassScript 识别这两种类型,并且一般来说,在编译输出的CSS文件中不会改变Sass文档中使用的字符串类型。
有一个例外,当使用 #{}
interpolation时,带引号的字符串将被编译为不带引号的字符串,这样主要是为了便于使用,比如mixins中的选择器名称。例如:
@mixin firefox-message($selector) {
body.firefox #{$selector}:before {
content: "Hi, Firefox users!";
}
}
@include firefox-message(".header");
编译为:
body.firefox .header:before {
content: "Hi, Firefox users!"; }
列表(Lists)
列表(lists) 是指 Sass 如何表示在CSS声明的,类似margin: 10px 15px 0 0
或 font-face: Helvetica, Arial, sans-serif
这样的值,列表只是一串其他值,无论是用空格还是用逗号隔开。事实上,独立的值也被视为列表:只包含一个值的列表。
列表本身没有太多的功能,但 Sass list functions 赋予了数组更多新功能:nth 函数可以直接访问数组中的某一项;join 函数可以将多个数组连接在一起;append 函数可以在数组中添加新值;而 @each 指令能够遍历数组中的每一项。
列表本身没有太多的功能,但是 SassScript list functions 使它们非常有用。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 中却是不同的:第一个是含两个列表的列表,而第二个是含有四个成员的列表。
用 () 表示不包含任何值的空数组(在 Sass 3.3 版之后也视为空的 map)。空数组不可以直接编译成 CSS,比如编译 font-family: () Sass 将会报错。如果数组中包含空数组或空值,编译时将被清除,比如 1px 2px () 3px 或 1px 2px null 3px。
列表也可以没有任何项。这些列表可以用 ()
表示(也是一个空的 map)。
它们不能直接输出到CSS;如果你试图这样做,例如font-family: ()
,Sass 将会报错。如果列表中包含空列表或空值,比如 1px 2px () 3px
或者 1px 2px null 3px
,在包含列表编译成CSS前,空列表和空值将被删除。
逗号分隔的列表可以保留结尾的逗号。这是特别有用,因为它可以表示一个 单个元素的列表。
例如,(1,)
表示为只包含1
的列表,而(1 2 3,)
这个表示包含一个列表,这个列表又包含以空格分隔的1
,2
, 和 3
的列表。
Maps
Maps代表一个键和值对集合,其中键用于查找值。他们可以很容易地将值收集到命名组中,并且可以动态地访问这些组。在CSS中你找不到和他们类似的值,虽然他们的语法类似于媒体查询表达式:
$map: (key1: value1, key2: value2, key3: value3);
和列表(Lists)不同,Maps必须始终使用括号括起来,并且必须用逗号分隔。Maps中的键和值可以是任意的SassScript对象。一个Maps可能只有一个值与给定的键关联(尽管该值可以是一个列表)。一个给定的值可能与许多键关联。
和列表(Lists)类似,Maps的主要操作使用的是 SassScript 函数。map-get
函数用于查找map中的值,map-merge
函数用于添加值到map中的值, @each
指令可以用来为 map 中的每个键值对添加样式。map中键值对的顺序和map创建时始终相同。
Maps还可以用于任何列表(Lists)能做的事情。当用于一个列表函数时,map被视为键值对列表。例如,(key1: value1, key2: value2)
被用于列表函数时,将被视为嵌套列表key1 value1, key2 value2
。列表不能被视为maps,不过,空列表除外。 ()
表示一个键/值对都没有的map,也可以被视为一个没有元素的列表。
需要注意的是 map 的建(keys)可以是任何 Sass 数据类型(甚至是另一个map),并且声明map的语法允许是任意的SassScript表达式,这个表达式将被评估为一个值以确定建(keys)。
Maps不能转换为纯CSS。作为变量的值或参数传递给CSS函数将会导致错误。使用inspect($value)
函数以产生输出字符串,这对于调试 maps 非常有用。
颜色(Colors)
任何CSS颜色表达式返回SassScript颜色值。这其中包括了大量的命名的颜色,这些名字字符串不区别带不带引号。
在压缩输出模式,Sass 将输出CSS简短的颜色表示法。例如,在压缩模式下 #FF0000
将输出为red
,但是blanchedalmond
将输出为 #FFEBCD
。
一个用户遇到的常见问题是在其它输出模式中Sass喜欢输出与命名的颜色相同的格式,当压缩的时候,插值到选择器的颜色变得无效语法。为了避免这种情况,如果他们是为了在选择施工中使用,总是给命名的颜色。
运算 (Operations)
所有数据类型的支持相等运算(==
和 !=
)。此外,每种类型都有其自己特殊的运算方式。
数字运算 (Number Operations)
SassScript 支持对数字标准的算术运算(加法+
,减法 -
,乘法*
,除法/
和取模%
)。Sass 数学函数在算术运算期间会保留单位。这意味着,就像在现实生活中,你不能用不相同的单位数字进行算术运算(比如数字后面添加了px
和em
单位),还有两个单位相同的数字相乘将产生单位平方(10px * 10px == 100px * px
)。要知道,px * px
是无效的CSS单位,Sass会抛出一个错误,因为你试图在CSS中使用无效的单位。
数字支持关系运算符(<
, >
, <=
, >=
),并且所有类型支持相等运算符(==
, !=
)。
除法和 /
(Division and /
)
CSS允许 /
出现在属性值之间作为分隔数字的方式(注:例如font属性,p.ex2{font:italic bold 12px/20px arial,sans-serif;}
)。由于SassScript是CSS属性语法的扩展,所以它必须支持这一点,同时还允许 /
用于除法。这意味着,在默认情况下,在SassScript中如果两个数字由 /
分隔,在返回的CSS中将以同样的方式出现。
但是,这里有将/
解析为除法三种情况。这些涵盖了绝大多数当做除法的案例。 他们是:
- 如果该值,或值的任何部分,存储在一个变量中或通过函数返回。
- 如果该值是由括号括起来的,除非这些括号是在一个列表(list)外部,并且值是括号内部。
- 如果该值被用作另一个算术表达式的一部分。
例如:
p {
font: 10px/8px; // 原生的CSS,不作为除法
$width: 1000px;
width: $width/2; // 使用了变量, 作为除法
width: round(1.5)/2;// 使用了函数, 作为除法
height: (500px/2); // 使用了括号, 作为除法
margin-left: 5px + 8px/2px; // 使用了 +, 作为除法
font: (italic bold 10px/8px); // 在一个列表(list)中,括号可以被忽略。
}
编译为:
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; }
减法,负数,和 -
(Subtraction, Negative Numbers, and -
)
在CSS和在Sass中 -
有许多不同的意义。它可以是一个减法运算符(比如在5px - 3px
中),也可以表示一个负数(比如在-3px
中),还可以是一个一元负运算符(比如在-$var
中),或是标识符的一部分(比如在font-weight
中)。大多数时候,我们可以很容易的分辨-
到底代表什么,但也有一些棘手的请客。以下作为一般规则,你是最安全的使用-
:
- 减法的时候,你总是在
-
两侧保留空格。 - 当表示一个负数或一元负运算时候,在
-
前面包含一个空格,后面不加空格。 - 如果在一个空格隔开的list(列表)中,你可以将一元负运算使用括号括起来,比如在
10px (-$var)
中。
-
的不同含义的优先顺序如下:
-
作为标识符的一部分。这意味着a-1
是一个不带引号的字符串,其值为"a-1"
。唯一的例外是单位;Sass 通常允许任何有效的标识符被用作一个标识符,但标识符不可能以数字或连字符开始。这意味着,5px-3px
和5px - 3px
是相同。-
在不带空格两个数字之间。这表明是减法,所以1-2
和1 - 2
是相同的。字面数字以
-
开头。这表明是一个负数,所以1 -2
是一个含有1
和-2
的 list(列表)。-
两个数字之间,不论是否带空格。这表明是减法,所以1 -$var
和1 - $var
是相同的。-
在值之前。这表明是一元负运算符;该操作需要一个数字,并返回其负值。
颜色运算 (Color Operations)
所有算术运算都支持的颜色值,颜色值的运算是分段进行计算的,也就是,依次计算红(red),绿(green),以及蓝(blue)的成分值。例如:
p {
color: #010203 + #040506;
}
计算 01 + 04 = 05
, 02 + 05 = 07
, 和 03 + 06 = 09
,并且编译为:
p {
color: #050709; }
通常color functions(颜色函数)比尝试使用颜色运算更加有用,以达到同样的效果。
数字和颜色值之间的算术运算也是分段。例如:
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); }
颜色的alpha通道可以使用opacify和transparentize函数进行调整。例如:
$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浏览器的滤镜(filters)要求所有的颜色包括 alpha 层,而且格式必须是固定的 #AABBCCDD ,使用 ie_hex_str 函数可以轻松的将颜色转化为 IE 滤镜所要求的格式。例如:
$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);
}
字符串运算 (String Operations)
+
运算可用于连接字符串:
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!"; }
布尔运算 (Boolean Operations)
SassScript 支持布尔值的 and
, or
, 和 not
运算。
列表运算 (List Operations)
数组不支持任何特殊运算,只能使用 list 函数 控制。
圆括号 (Parentheses)
圆括号可以用来影响运算的顺序(注:优先级):
p {
width: 1em + (2em * 3);
}
编译为:
p {
width: 7em; }
函数 (Functions)
SassScript定义了一些有用的函数, 这些函数可以像普通 CSS 函数语法一样调用:
p {
color: hsl(0, 100%, 50%);
}
编译为:
p {
color: #ff0000; }
可用函数的完整列表,请参阅这张页面。
关键词参数 (Keyword Arguments)
Sass 函数允许指定明确的关键词参数 (keyword arguments) 进行调用。 上面的例子也可以改写成:
p {
color: hsl($hue: 0, $saturation: 100%, $lightness: 50%);
}
虽然不够简明,但可以让Sass代码阅读起来更加方便。 关键词参数让函数具有更灵活的接口, 即便参数众多,也不会让使用变得困难。
命名参数(named arguments)可以以任意顺序传入,并且,具有默认值的参数可以省略掉。 由于命名参数也是变量名称,因此,下划线、短横线可以互换使用。
完整的 Sass 函数列表和它们的参数名称,以及在 Ruby 里如何定义你自己的函数的步骤,请见 Sass::Script::Functions。
插值:#{}(
Interpolation: #{}
)
您还可以通过 #{}
插值语法在选择器和属性名中使用 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中的&
(&
in SassScript)
就像当它在选择器中使用一样,SassScript中的&
指向当前父选择器。下面是一个逗号分隔的列表(list)中包含一个空格的分隔列表(list)。例如:
.foo.bar .baz.bang, .bip.qux {
$selector: &;
}
$selector
的值是现在 ((".foo.bar" ".baz.bang"), ".bip.qux")
。这个混合选择器在这里加了引号,以表明他们是字符串,但在现实中,他们将不带引号的。即使选择器不包含逗号或空格,&
总会有两个嵌套层次,因此它可以保证访问一致性。
如果没有父选择器,&
的值将是空。这意味着你可以在一个mixin中使用它来检测父选择是否存在:
@mixin does-parent-exist {
@if & {
&:hover {
color: red;
}
} @else {
a {
color: red;
}
}
}
变量默认: !default
(Variable Defaults: !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"; }
通过!default赋值的时候,如果变量是 null
值时,将视为未赋值(注:所以下面的$content值为 "Non-null content"):
$content: null;
$content: "Non-null content" !default;
#main {
content: $content;
}
编译为:
#main {
content: "Non-null content"; }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论