Sass/Scss 学习总结(六) 之 混合指令和函数

混合器(@mixin)

混合(mixin)允许您定义可以在整个样式表中重复使用的样式,而避免了使用无语意的类(class),比如:.float-left。混合(mixin)还可以包含所有的 CSS 规则,以及任何其他在 Sass 文档中被允许使用的东西。

定义

mixin 名称(参数?) { 内容块; }

混合(mixin)通过 @mixin 指令定义。在它后面跟混合的名称和可选参数,以及混合的内容块,例如:

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

混合也可以包含选择器和属性的混合体,选择器中甚至可以包含 &(父选择器),例如:

@mixin clearfix {
    display: inline-block;

    &:after {
    	content: ".";
	display: block;
	height: 0;
	clear: both;
	visibility: hidden;
    }

    * html & { height: 1px; }
}

由于历史原因,混入(mixin)的名字(和所有其他 Sass 标识符)可以互换连字符和下划线。例如,如果你定义了一个名为add-column的混入,你可以把它作为add_column,反之亦然。


引入混合器

使用 @include 指令可以将混合(mixin)引入到文档中。这需要一个混合的名称和可选的参数传递给它,并包括由混合定义的当前规则的样式。例如:

// b.scss 文件
// -------------------------------------------

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

    & span {
	color: red;
    }
}

.page-title {
    @include large-text;
    padding: 4px;
    margin-top: 10px;
}


// 编译后的 b.css 文件
// -------------------------------------------

.page-title {
    font-family: Arial;
    font-size: 20px;
    font-weight: bold;
    color: #f00;
    padding: 4px;
    margin-top: 10px;
}

.page-title span {
    color: red;
}

混合(mixin)也可以包含在任何规则之外(即,在文档的根),只要它们不直接定义的任何属性或使用任何父选择器引用。例如:

// b.scss 文件
// -------------------------------------------

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

@include silly-links;


// 编译后的 b.css 文件
// -------------------------------------------

a {
    color: blue;
    background-color: red; 
}

混合器(mixin)也可以包含其它的混合器,例如:

// b.scss 文件
// -------------------------------------------

@mixin color {
    color: #f00;
}

@mixin font {
    @include color;
    font-size: 12px;
}

.page-title {
    @include font;
}


// 编译后的 b.css 文件
// -------------------------------------------

.page-title {
    color: #f00;
    font-size: 12px;
}


带参混合器

混合器(mixin)可以用 SassScript 值作为参数,给定的参数被包括在混合(mixin)中并且作为为变量提供给混合器。

当定义一个混合器(mixin)的时候,参数被作为变量名,写到混合器(mixin)名字后面的括号内,多个参数可以用逗号分隔。然后,当调用混合器的时候,值通过对应的参数顺序被传递。例如:

// b.scss 文件
// -------------------------------------------

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

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


// 编译后的 b.css 文件
// -------------------------------------------

p {
    border-color: blue;
    border-width: 2px;
    border-style: dashed;
}

混合器(mixin)也可以使用普通的变量赋值语法为参数指定默认值。然后,当调用混合器的时候,如果没有给参数赋值,则自动会使用默认值代替。例如:

// b.scss 文件
// -------------------------------------------

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

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

h1 {
    @include sexy-border(blue, 2px);
}


// 编译后的 b.css 文件
// -------------------------------------------

p {
    border-color: blue;
    border-width: 1px;
    border-style: dashed;
}

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


关键字参数

混合器(mixin)在引入(@include指令)的时候也可以使用明确的关键字参数。例如,上面的例子可以写成:

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

虽然这是不够简明,但是它可以使样式表更容易阅读。它给函数呈现了更加灵活的接口,它使多参数的混合器更加容易调用。

命名的参数可以按任何顺序进行传递,有默认值的参数可以省略。由于命名参数是变量名,下划线和连字符可以互换使用。


可变参数

有时,不能确定一个混合器(mixin)或者一个函数(function)使用多少个参数。例如,用于创建盒子阴影(box-shadow)的一个混入(mixin)可以采取任何数量的 box-shadow 作为参数。对于这些情况,Sass支持"可变参数",参数在声明混合(mixin)或函数(function)结束的地方,所有剩余的参数打包成一个列表(list)。参数看起来就像普通参数一样,但后面跟随着...。例如:

// b.scss 文件
// -------------------------------------------

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


// 编译后的 b.css 文件
// -------------------------------------------

.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)或者函数(function)。这些可以使用keywords($args) 函数]来访问,返回一个 map,参数名称字符串( 无 $ )和值的键值对。

可变参数,也可以在调用(@include指令)一个混合器(mixin)时使用。使用相同的语法,你可以扩展值的列表(list),以便每个值作为单独的参数传入,或扩展值的 map,以使每个键值对作为一个关键字参数处理。例如:

// b.scss 文件
// -------------------------------------------

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


// 编译后的 b.css 文件
// -------------------------------------------

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

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

你可以同时传递一个列表(list)和一个map参数,只要列表(list)在 map 上之前,比如 @include colors($values..., $map...)。

您可以使用可变参数来包装一个混入(mixin)并且添加额外的样式,而不改变混入(mixin)的参数签名。如果你这样做,关键字参数将通过包装的混入(mixin)直接传递。例如:


传递内容块到混合器

样式内容块可以传递到混合器(mixin)包含样式的位置。样式内容块将出现在混合器内的任何 $content 指令的位置,这使得可以定义抽象关联到选择器和指令的解析。例如:

// b.scss 文件
// -------------------------------------------

@mixin apply-to-ie6-only {
    * html {
        @content;
    }
}

@include apply-to-ie6-only {
    #logo {
        background-image: url(/logo.gif);
    }
}


// 编译后的 b.css 文件
// -------------------------------------------

* html #logo {
    background-image: url(/logo.gif);
}

注意: 当 @content 指令指定多次或在一个循环中指定的时候,样式块将在每次调用中被复制并引用。


变量的作用域和内容块

传递给混合器(mixin)的内容块在其被定义的作用域中进行运算,而不是混合器(mixin)的作用域。这意味着混合器(mixin)的局部变量不能传递给样式块使用,并且变量将解析为全局值:

// b.scss 文件
// -------------------------------------------

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

.colors {
    @include colors {
        color: $color;
    }
}


// 编译后的 b.css 文件
// -------------------------------------------

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

另外,这清楚地表明,变量和传递到块中使用的混合,指向块定义的周围其他样式。例如:

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


函数(function)

Sass 支持自定义函数,并能在任何值或脚本上下文中使用。自定义函数格式和混合器格式一样,只不过,把关键字 @mixin 换成 @function,例如:

// b.scss 文件
// -------------------------------------------

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

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

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


// 编译后的 b.css 文件
// -------------------------------------------

#sidebar {
    width: 240px;
}

正如你看到的,函数可以访问任何全局定义的变量,以及接受参数,就像一个混入(mixin)。函数可以包含语句,并且你必须调用@return来设置函数的返回值。

与混入(mixin)一样,你可以使用关键字参数来调用Sass定义的函数。在上面的例子中,我们可以这样调用函数:

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

建议您在函数前加上前缀,以避免命名冲突,其他人阅读样式表的时候也会知道它们不是 Sass 或者 CSS 的自带功能。例如,如果您在 ACME 公司工作,你可以给上面的函数取名为-acme-grid-width。

用户自定义的函数也支持可变参数,方式和混入(mixin)是相同的。

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


未经允许不得转载:易读小屋  »  Sass/Scss 学习总结(六) 之 混合指令和函数