大纲
1、嵌套规则(Nested Rules)
2、父选择符: &
3、嵌套属性
4、SassScript
5、@ 规则和指令
6、控制指令(Control Directives)
7、Mixin Directives
8、Function Directives
1、嵌套规则(Nested Rules)
Sass允许CSS规则相互嵌套。内部规则只应用于外部规则的选择器。
这有助于避免重复父选择器,并使具有许多嵌套选择器的复杂CSS布局更加简单。
#main {
width: 97%;
p,
div {
font-size: 2em;
a {
font-weight: bold;
}
}
pre {
font-size: 3em;
}
}
/*
scss编译为:css语法
*/
#main {
width: 97%;
}
#main p,
#main div {
font-size: 2em;
}
#main p a,
#main div a {
font-weight: bold;
}
#main pre {
font-size: 3em;
}
2、父选择符: &
当选择器拥有某种特殊效果(如悬停)或者父选择器有特定类的时候,需要对这些情况设置某种样式,在这些情况下,可以使用&字符显式指定应该插入父选择器的位置。
& 在编译时将被替换为父选择符,输出到 CSS 中。 也就是说,如果你有一个深层嵌套的规则,父选择符也会在 & 被替换之前被完整的解析。
#main {
color: black;
a {
font-weight: bold;
&:hover {
color: red;
}
}
}
/*
编译为
*/
#main {
color: black;
}
#main a {
font-weight: bold;
}
#main a:hover {
color: red;
}
3、嵌套属性
CSS有相当多的属性位于“名称空间”中;
例如,font-family、font-size和font-weight都位于font(字体)名称空间中。
在CSS中,如果想在相同的名称空间中设置一些属性,每次都必须键入它。Sass为此提供了一个快捷方式:只需编写一次名称空间,然后在其中嵌套每个子属性。
/*
scss
*/
.funky {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}
/*
编译为:
*/
.funky {
font-family: fantasy;
font-size: 30em;
font-weight: bold;
}
4、SassScript
除了普通的CSS属性语法,Sass还支持一组名为SassScript的扩展。
SassScript允许属性使用变量、算术和其他函数。SassScript可以用于任何属性值。
SassScript还可以用来生成选择器和属性名,这在编写mixin时非常有用。这是通过插值来实现的。
4.1、算术
>> "Hello, Sassy World!"
"Hello, Sassy World!"
>> 1px + 1px + 1px
3px
>> #777 + #777
#eeeeee
>> #777 + #888
white
4.2、Variables(变量): $
/*
使用SassScript最直接的方法是使用变量。变量以美元符号开头,设置类似CSS属性
*/
$width: 5em;
/*
然后你可以在属性中引用它们:
*/
#main {
width: $width;
}
/*
变量只能在定义变量的嵌套选择器级别内可用。如果它们是在任何嵌套选择器之外定义的,
那么它们在任何地方都是可用的。
*/
4.3、函数
/*
SassScript 定义了一些有用的函数, 这些函数可以像普通 CSS 函数语法一样被调用:
*/
p {
color: hsl(0, 100%, 50%);
}
/*
被编译为:
*/
p {
color: #ff0000;
}
/*
关键词参数:
Sass 函数允许指定明确的关键词参数 (keyword arguments) 进行调用。
虽然不够简明,但可以让样式表阅读起来会更方便。 关键词参数让函数具有更灵活的接口,
即便参数众多,也不会让使用变得困难。
命名参数(named arguments)可以以任意顺序传入,并且,具有默认值的参数可以省略掉。
由于命名参数也是变量名称,因此,下划线、短横线可以交换使用。
*/
/*
上面的例子也可以写成:
*/
p {
color: hsl($hue: 0, $saturation: 100%, $lightness: 50%);
}
4.4、Interpolation(插值): #{}
/*
可以在选择器和属性名中使用SassScript变量,使用#{}插值语法:
*/
$name: foo;
$attr: border;
p.#{$name} {
#{$attr}-color: blue;
}
/*
被编译为:
*/
p.foo {
border-color: blue;
}
4.5、变量默认值: !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 当做没有值:
*/
$content: null;
$content: "Non-null content" !default;
#main {
content: $content;
}
/*
被编译为:
*/
#main {
content: "Non-null content";
}
5、@ 规则和指令
Sass 支持所有 CSS3 的 @ 规则, 以及一些 Sass 专属的规则,也被称为“指令(directives)”。 这些规则在 Sass 中具有不同的功效。
5.1、@import
Sass 扩展了 CSS 的 @import 规则,让它能够引入 SCSS 和 Sass 文件。 所有引入的 SCSS 和 Sass 文件都会被合并并输出一个单一的 CSS 文件。 另外,被导入的文件中所定义的变量或 mixins 都可以在主文件中使用。
@import 根据文件名引入。 默认情况下,它会寻找 Sass 文件并直接引入, 但是,在少数几种情况下,它会被编译成 CSS 的 @import 规则:
i:如果文件的扩展名是 .css。
ii:如果文件名以 http:// 开头。
iii:如果文件名是 url()。
iv:如果 @import 包含了任何媒体查询(media queries)。
如果上述情况都没有出现,并且扩展名是 .scss 或 .sass, 该名称的 Sass 或 SCSS 文件就会被引入。 如果没有扩展名, Sass 将试着找出具有 .scss 或 .sass 扩展名的同名文件并将其引入。
/*
两者都将引入 foo.scss 文件
*/
@import "foo.scss";
@import "foo";
@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 两个文件。
*/
5.2、片段
如果你有一个 SCSS 或 Sass 文件需要引入, 但是你又不希望它被编译为一个 CSS 文件, 这时,你就可以在文件名前面加一个下划线,就能避免被编译。 这将告诉 Sass 不要把它编译成 CSS 文件。 然后,你就可以像往常一样引入这个文件了,而且还可以省略掉文件名前面的下划线。
/*
例如,你有一个文件叫做 _colors.scss。 这样就不会生成 _colors.css 文件了
而且你还可以这样做:
*/
@import "colors";
/*
来引入 _colors.scss 文件。
*/
注意,在同一个目录不能同时存在带下划线和不带下划线的同名文件。 例如, _colors.scss 不能与 colors.scss 并存。
5.3、嵌套 @import
虽然大部分时间只需在顶层文件使用 @import 就行了, 但是,你还可以把他们包含在 CSS 规则 和 @media 规则中。
/*example.scss*/
.example {
color: red;
}
/* use */
#main {
@import "example";
}
/* 编译为 */
#main .example {
color: red;
}
5.4、@media
Sass中的@media指令就像普通CSS中的指令一样,有一个额外的功能:它们可以嵌套在CSS规则中。如果@media指令出现在CSS规则中,它将冒泡到样式表的顶层,将所有选择器放到规则中。这使得添加特定于媒体的样式变得很容易,而无需重复选择器或中断样式表的流程。
.sidebar {
width: 300px;
@media screen and (orientation: landscape) {
width: 500px;
}
.header {
width: 300px;
@media screen and (orientation: landscape) {
width: 500px;
}
}
}
/* 编译为: */
.sidebar {
width: 300px;
}
@media screen and (orientation: landscape) {
.sidebar {
width: 500px;
}
}
.sidebar .header {
width: 300px;
}
@media screen and (orientation: landscape) {
.sidebar .header {
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;
}
}
5.5、@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。这是一个维护负担,
会导致一些棘手的bug,并可能将非语义样式的关注点引入标记。
@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 {
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;
}
5.5.1、复杂选择器的继承(Extending Complex Selectors)
/*
类选择器不是惟一可以扩展的东西。可以扩展只涉及单个元素的任何选择器,
例如 .special.cool, a:hover, or 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一样,任何使用:hover的规则也适用于.hoverlink,
即使它们也有其他选择器。
*/
.hoverlink {
@extend a:hover;
}
.comment a.user:hover {
font-weight: bold;
}
/* 被编译为: */
.comment a.user:hover,
.comment .user.hoverlink {
font-weight: bold;
}
5.5.2、多继承(Multiple Extends)
/*
单个选择器可以扩展多个选择器。这意味着它继承了所有扩展选择器的样式。
*/
.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相同。
*/
5.5.3、链接扩展(Chaining Extends)
/*
一个选择器可以扩展另一个选择器,而另一个选择器又可以扩展第三个选择器。
*/
.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%;
}
/* 编译为:*/
.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%;
}
5.5.4、选择器序列(Selector Sequences)
/*
选择器序列,例如.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;
}
5.5.5、合并选择序列
有时选择器序列会扩展另一个序列中出现的另一个选择器。在这种情况下,这两个序列需要合并。
虽然在技术上可以生成所有可能匹配这两个序列的选择器,但是这会使样式表太大。例如,上面的简单示例需要10个选择器。相反,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;
}
5.5.6、只继承选择器(@extend-Only Selectors)
有时候,您会为一个类编写样式,而这个类只需要@extend,而不需要直接在HTML中使用。在编写Sass库时尤其如此,如果用户需要,您可以为他们提供@extend样式,如果用户不需要,您可以忽略。
如果为此使用普通类,那么在生成样式表时就会创建许多额外的CSS,并有可能与HTML中使用的其他类发生冲突。这就是为什么Sass支持“占位符选择器”(例如%foo)。
占位符选择器看起来像类和id选择器,除了 # or . 替换为%。它们可以在类或id可以使用的任何地方使用,并且它们本身可以防止规则集被呈现到CSS。
/* This ruleset won't be rendered on its own. */
#context a%extreme {
color: blue;
font-weight: bold;
font-size: 2em;
}
/*
但是,占位符选择器可以扩展,就像类和id一样。将生成扩展的选择器,
但不会生成基本占位符选择器。
*/
.notice {
@extend %extreme;
}
/*
以上单独存在没有效果,Sass也不会编译出来,只有两者共同存在才会进行编译,
简单的理解就是:类notice继承了#context a的类,或者可以理解为notice在#context a的基础上
扩展
*/
#context a.notice {
color: blue;
font-weight: bold;
font-size: 2em;
}
5.5.7、可选标志(The !optional Flag)
通常在扩展选择器时,如果@extend不起作用,就会出现错误。例如,如果你写a.important{@extend .notice},如果没有包含.notice的选择器,这是一个错误。如果唯一包含.notice的选择器是h1,这也是一个错误。注意,由于h1与a冲突,因此不会生成新的选择器。
但是,有时您希望允许@extend不产生任何新的选择器。为此,只需在选择器之后添加!optional标志。
// 不加 !optional 会报错
a.important {
@extend .notice !optional;
}
a.important {
@extend .notice!optional;
}
h1.notice {
color: red;
}
/* 编译为*/
h1.notice {
color: red;
}
// 注意.notice是h1标签上的,与下面的代码是有区别的
a.important {
@extend .notice!optional;
}
h1 .notice {
color: red;
}
/* 编译为:*/
h1 .notice, h1 a.important {
color: red;
}
5.5.8、指令中的继承(@extend in Directives)
在@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;
}
}
5.6、@debug
@debug指令将SassScript表达式的值打印到标准错误输出流。它对于调试具有复杂SassScript的Sass文件非常有用。
@debug 10em + 12em;
/* outputs: */
Line 1 DEBUG: 22em
5.7、@warn
@warn指令将SassScript表达式的值打印到标准错误输出流。对于需要提醒用户注意弃用或从轻微混合使用错误中恢复的库,它非常有用。@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;
}
6、控制指令(Control Directives)
SassScript支持基本的控制指令,用于只在某些条件下包含样式,或者多次包含相同的样式,并带有变体。
注意,控制指令是一个高级特性,在日常样式化过程中不推荐使用。它们主要用于mixin中,特别是那些属于Compass这样的库的部分,因此需要很大的灵活性。
6.1、@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;
}
/*
@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;
}
6.2、@for
/*
for指令重复输出一组样式。对于每个重复项,计数器变量用于调整输出。
这个指令有两种形式:@for $var,从<start>到<end>; @for $var,从<start>到<end>。
注意关键字through和to的区别。
$var可以是任何变量名,比如$i;
<start>和<end>是应该返回整数的SassScript表达式。
@for语句将$var设置为指定范围内的每个连续数字,每次使用$var的值输出嵌套样式。
对于from ... through,范围包括<start>和<end>的值,
但是from ... to,范围运行到但不包括<end>的值。
*/
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
/* 编译为 */
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
.item-3 {
width: 6em;
}
6.3、@each
/*
$var可以是任何变量名,比如$length或$name,它是一个返回列表的SassScript表达式。
@each规则将$var设置为列表中的每个项目,然后使用$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");
}
6.4、@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;
}
7、Mixin Directives
mixin允许您定义可以在整个样式表中重用的样式,而不需要求助于.float-left之类的非语义类。mixin还可以包含完整的CSS规则,以及Sass文档中其他任何允许的内容。它们甚至可以使用参数,允许您使用非常少的混合创建各种风格。
7.1、定义一个Mixin:Defining a Mixin: @mixin
/*
mixin是用@mixin指令定义的。后面是mixin的名称和可选的参数,以及包含mixin内容的块。
例如,large-text Mixin的定义如下:
*/
@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
}
/*
mixin也可能包含选择器,可能与属性混合。选择器甚至可以包含父引用。例如:
*/
@mixin clearfix {
display: inline-block;
&:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
* html & {
height: 1px;
}
}
7.2、引入一个Mixin:Including a 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不得直接或间接地包括其本身。也就是说,mixin递归是禁止的。
仅定义派生选择器的mixin可以安全地混合到文档的最顶层。
*/
7.3、参数:Arguments
/*
mixin可以将参数SassScript值作为参数,这些参数在包含mixin时给出,
并在mixin中作为变量提供。
在定义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。例如,我们上面的例子可以写成:
*/
@mixin sexy-border($color, $width: 1in) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
p {
@include sexy-border($color: blue);
}
h1 {
@include sexy-border($color: blue, $width: 2in);
}
/*
虽然这不够简洁,但可以使样式表更易于阅读。它还允许函数提供更灵活的接口,
提供许多参数,而不会变得难以调用。
命名参数可以按任何顺序传递,具有默认值的参数可以省略。
由于命名参数是变量名,下划线和破折号可以互换使用。
*/
7.4、变量参数
/*
有时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时也可以使用变量参数。使用相同的语法,您可以展开一个值列表,
以便将每个值作为单独的参数传递。例如:
*/
@mixin colors($text, $background, $border) {
color: $text;
background-color: $background;
border-color: $border;
}
$values: #ff0000, #00ff00, #0000ff;
.primary {
@include colors($values...);
}
/* 编译为 */
.primary {
color: #ff0000;
background-color: #00ff00;
border-color: #0000ff;
}
/*
您可以使用变量参数来包装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);
}
7.5、将内容块传递给Mixin(Passing Content Blocks to a 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);
}
/*
可以使用.sass简写语法进行相同的混合:
*/
=apply-to-ie6-only
* html
@content
+apply-to-ie6-only
#logo
background-image: url(/logo.gif)
/*
注意:当@content指令不止一次指定或在循环中指定时,样式块将在每次调用时复制。
*/
/*
可变范围和内容块
传递给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;
}
}
8、Function Directives
/*
可以在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相同的方式支持变量参数。
*/