标签:
当样式变得越来越复杂,需要重复大段的样式,声明一个个变量已经不能满足我们的需求时,这时Sass中的混合宏就会变得非常有意义。Less中同样有这部分类容,有带参数的混合和不带参数的混合。
1、声明混合宏
不带参数混合宏
在Sass中,使用”@mixin”来声明一个混合宏,如:
@mixin border_radius {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
@mixin是用来声明混合宏的关键词,border-radius是混合宏的名称。
定义混合宏,不会编译在CSS中,只有被调用时,才会编译。
使用@include调用混合宏
div {
@include border-radius;
}
编译的CSS如下:
div {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
2、带参数的混合宏
@mixin border_radius($radius) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
border-radius: $radius;
}
调用混合宏
div{
@include border-radius(5px);
}
编译的CSS如下:
div {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
3、带默认值的混合宏
@mixin border_radius($radius:10px) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
border-radius: $radius;
}
调用混合宏
div {
@include border_radius;
}
编译后的CSS如下:
div {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
当项目中很多地方都需要用到10px的border-radius时,我们可以设置默认值。
在需要特别设置的值时,只需要给其传递参数即可。
如:
div {
@include border_radius(50%);
}
编译后的CSS如下:
div {
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 50%;
}
混合宏的参数——多个参数
sass混合可以传递多个参数,如:
@mixin box($width,$height) {
width:$width;
height: $height
}
调用混合宏:
div{
@include box(200px, 300px);
}
编译后的css为:
div {
width: 200px;
height: 300px;
}
同样,多个参数时,也可以设置默认值。
有一个特别的参数“…”.当混合宏传递的参数过多时,可以使用该参数替代,如:
@mixin box-shadow($shadows...){
@if length($shadows) >= 1 {
-webkit-box-shadow: $shadows;
box-shadow: $shadows;
} @else {
$shadows: 0 0 2px rgba(#000,.25);
-webkit-box-shadow: $shadow;
box-shadow: $shadow;
}
}
调用混合宏:
.box {
@include box-shadow(0 0 1px rgba(#000,.5),0 0 2px rgba(#000,.2));
}
编译后的css:
.box {
-webkit-box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
}
4、复杂的混合宏
混合宏中可以有逻辑关系.比LESS的匹配高级一点
@mixin triangle($direction, $width:5px, $color:#ccc){
border-width: $width;
width:0;
height:0;
overflow:hidden;
@if($direction == "top"){
border-color: transparent transparent $color transparent;
border-style: dashed dashed solid dashed;
}@else if($direction == "bottom"){
border-color: $color transparent transparent transparent;
border-style: solid dashed dashed dashed;
}@else if($direction == "left"){
border-color: transparent $color transparent transparent;
border-style: dashed dashed solid dashed;
}@else{
border-color: transparent transparent transparent $color;
border-style: dashed dashed dashed solid;
}
}
以上代码用于生成三角形。通过判断$direction的值来设置不同的样式。
调用混合宏:
div{
@include triangle("top")
}
编译后的CSS:
div {
border-width: 5px;
width: 0;
height: 0;
overflow: hidden;
border-color: transparent transparent #ccc transparent;
border-style: dashed dashed solid dashed;
}
混合宏在实际编码中带来很多方便,特别是对于重复的代码块。但是其最大的不足之处在于会生成冗余的代码块。
如:
@mixin box($width:50px,$height:50px) {
width:$width;
height: $height
}
div{
@include box;
}
img{
@include box;
}
编译出来的css:
div {
width: 50px;
height: 50px;
}
img {
width: 50px;
height: 50px;
}
调用相同的混合宏,但是不能智能的将样式代码合并在一起。
CSS中存在继承,子元素比继承父元素的样式。同样,sass中也存在继承。
.btn {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
.btn-primary {
background-color: #f36;
color: #fff;
@extend .btn;
}
.btn-second {
background-color: orange;
color: #fff;
@extend .btn;
}
编译出来的CSS:
.btn, .btn-primary, .btn-second {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
.btn-primary {
background-color: #f36;
color: #fff;
}
.btn-second {
background-clor: orange;
color: #fff;
}
在 Sass 中的继承,可以继承类样式块中所有样式代码,而且编译出来的 CSS 会将选择器合并在一起,形成组合选择器.
占位符可以取代CSS中基类造成的代码冗余的情景,如上个例子中,即使.btn不被调用,也会在CSS中编译出来。而如果使用%placeholder声明,如果不被@extend调用的话,不会产生任何代码,这一点,在LESS中在声明时,加一个括号也可以实现,即:.btn(){};
如:
%border-radius{
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
这段代码在没有被@extend调用之前,不会在CSS中产生任何代码。
调用:
div{
@extend %border-radius;
}
编译后的CSS:
div {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
Sass中的混合宏:
混合宏不会自动合并相同的样式代码,如果在样式文件中调用同一个混合宏,会产生多个对应的样式代码,造成代码的冗余。但是,如果代码中涉及变量,建议使用混合宏来创建相同的代码块,因为混合宏可以传递参数。
Sass中继承
使用继承时,编译出来的CSS会将使用继承的代码合并到一块,通过组合选择器的方式向大家展现,但是它不能传参数。
占位符
编译出来的 CSS 代码和使用继承基本上是相同,只是不会在代码中生成占位符 mt 的选择器。那么占位符和继承的主要区别的,“占位符是独立定义,不调用的时候是不会在 CSS 中产生任何代码;继承是首先有一个基类存在,不管调用与不调用,基类的样式都将会出现在编译出来的 CSS 代码中。
总结:
方式 | 混合宏 | 继承 | 占位符 |
---|---|---|---|
声明方式 | @mixin | .class | %placeholder |
调用方式 | @include | @extend | @extend |
使用环境 | 如果相同代码块需要在不同的环境传递不同的值时,可以通过混合宏来定义重复使用的代码块。==不足==:不会自动合并相同的代码块,造成代码冗余。 | 如果相同代码块不需要传递不同的值,并且此代码块已在Sass中定义,此时可以通过Sass的继承来调用已存在的基类。使用继承会将相同的代码块合并在一起。 ==不足==:如果基类,不存在于HTML结构时,不管调用与否,都会在CSS中编译出基类对应的代码样式 | 占位和继承类似,不管在不调用时,不会再CSS中产生代码。 |
$properties: (margin, padding);
@mixin set-value($side, $value) {
@each $prop in $properties {
#{$prop}-#{$side}: $value;
}
}
.login-box {
@include set-value(top, 14px);
}
$property: (left, right, top, bottom);
@mixin set-pro($side, $value){
@each $prop in $property{
#{$side}-#{$prop}: $value;
}
}
.box{
@include set-pro(margin, 20px)
}
编译出来的CSS:
.login-box {
margin-top: 14px;
padding-top: 14px;
}
.box {
margin-left: 20px;
margin-right: 20px;
margin-top: 20px;
margin-bottom: 20px;
}
@each in 和JS中的for in类似,遍历整个数组。
当想要设置属性值的时候可以使用字符串插入进来,另一个有用的用法是构建一个选择器。
@mixin generate-sizes($class, $small, $medium, $big) {
.#{$class}-small { font-size: $small; }
.#{$class}-medium { font-size: $medium; }
.#{$class}-big { font-size: $big; }
}
@include generate-sizes("header-text", 12px, 20px, 40px);
编译出来的CSS:
.header-text-small { font-size: 12px; }
.header-text-medium { font-size: 20px; }
.header-text-big { font-size: 40px; }
$margin-big: 40px;
$margin-medium: 20px;
$margin-small: 12px;
@mixin set-value($size) {
margin-top: $margin-#{$size};
}
.login-box {
@include set-value(big);
}
这样使用不会得到我们期望的结果,在第五行会报错。因为#{}语法在这里不能被使用。
对上面的代码稍作更改:
$margin-big: 40px;
$margin-medium: 20px;
$margin-small: 12px;
@mixin set-value($size) {
margin-#{$size}: 19px;
}
.login-box {
@include set-value(big);
}
编译出来的CSS:
.login-box {
margin-big: 19px;
}
这样可以作用之后,既然在:右侧不行,那么使用@include呢?很容易会想到尝试下面这样的写法。
$margin-big: 40px;
$margin-medium: 20px;
$margin-small: 12px;
@mixin set-value($size) {
@include $margin-#{$size}
}
编译时同样报错:Error: Invalid CSS after ” @include “: expected identifier, was “margin-#{size}”
尽管以上做法依旧行不通,幸运的是,我们可以在@extend中使用插值,例如:
%updated-status {
margin-top: 20px;
background: #F00;
}
.selected-status {
font-weight: bold;
}
$flag: "status";
.navigation {
@extend %updated-#{$flag};
@extend .selected-#{$flag};
}
编译后的CSS:
.navigation {
margin-top: 20px;
background: #F00;
}
.selected-status, .navigation {
font-weight: bold;
}
SASS中的注释规则和LESS一样。可以使用”//”或者是以”/*”开头,以”*/”结尾。
两者的区别在于,//的注释不会在编译后的CSS中显示出来。
而以”/*”开头,以”*/”结尾的注释会在编译后的CSS中显示。
Sass 和 JavaScript 语言类似,也具有自己的数据类型,在 Sass 中包含以下几种数据类型:
SassScript 也支持其他 CSS 属性值(property value),比如 Unicode 范围,或 !important 声明。然而,Sass 不会特殊对待这些属性值,一律视为无引号字符串 (unquoted strings)。
Sass支持CSS的两种字符串类型:
@mixin message($selector) {
body #{$selector}:before {
content: "Hi, Firefox users!";
}
}
@include message(".header");
编译出来的CSS:
body .header:before {
content: "Hi, Firefox users!";
}
所谓值列表是指Sass如何处理CSS中:
margin: 10px 20px 20px 30px;
或者:
box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
向这种用逗号或者是空格分隔的一系列的值。
独立的值可以被视为只包含一个值的值列表。
Sass列表函数赋予了值列表更多功能:
1. nth函数(nth function) 可以直接访问值列表中的某一项;
2. join函数(join function) 可以将多个值列表连结在一起;
3. append函数(append function) 可以在值列表中添加值;
4. @each规则(@each rule) 则能够给值列表中的每个项目添加样式;
值列表中可以再包含值列表,比如 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 文件中却有不同的意义,前者是包含两个值列表的值列表,而后者是包含四个值的值列表。
可以用 () 表示空的列表,这样不可以直接编译成 CSS,比如编译 font-family: ()时,Sass 将会报错。如果值列表中包含空的值列表或空值,编译时将清除空值,比如 1px 2px () 3px 或 1px 2px null 3px。
标签:
原文地址:http://blog.csdn.net/liuyan19891230/article/details/52192203