混入
@mixin和@inclue的基本使用
@mixin混入可以用于定义重复使用的样式,比如下面CSS代码
.header {
display: flex;
justify-content: center;
align-items: center;
width: 500px;
height: 100px;
}
.footer {
display: flex;
justify-content: center;
align-items: center;
width: 1400px;
height: 50px;
}
我们可以发现,.header和.footer存在相同重复的样式定义,此时SCSS可以将这段重复样式提取到混入@mixin中,再在.header和.footer中通过@inclue引入混入样式
@mixin center {
display: flex;
justify-content: center;
align-items: center;
}
.header {
@include center;
width: 500px;
height: 100px;
}
.footer {
@include center;
width: 1400px;
height: 50px;
}
带参数的@mixin和@include
@mixin定义的样式支持接收外部参数,来作为内部样式的值,如下 @mixin flex($justify,$align)接收了两个参数$justify,$align,并且这两个参数作为了混入样式justify-content、align-item的值。
@mixin定义参数,需要通过@include来传递值,如下.header中@include flex(start,center)传了start给$justify,传了center给@align,而这种传参方式是顺序传参,即传参顺序严格按照@mixin定义的参数顺序来。
@include指定传参
@include除了可以顺序传参外,还支持指定传参,即不按照@mixin定义的参数顺序传值
@mixin的参数默认值
当@mixin样式需要的入参较多时,一般会设置一些默认值,来减轻@include传参压力,即对于有默认值的参数,@include可以不传值
@mixin可变参数
有一些样式的值可以无穷传,比如backgroud:linear-gradient,此时我们无法通过手动定义无穷个@mixin参数来接收,需要使用可变参数来接收,可变参数和普通参数的区别在于,可变参数名字后面需要紧跟着三个点
上面代码中@mixin有两个参数,$direct是普通参数,$colors是可变参数,当@include传参时,第一个参数90deg传给了$direct,其余参数都传递给了$colors。
@mixin的使用场景
多个样式类,如果具有重复的样式属性名,但是样式属性值不同,此时可以将这些重复的样式提取到混入@mixin中定义,可以有效的减少代码。
@mixin嵌套写法
@mixin large-text {
font: { //scss允许这种写法,但是基本不咋用
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
a {
color: blue;
background-color: red;
}
}
//使用
page-title {
@include large-text;
padding: 4px;
margin-top: 10px;
}
编译后
.page-title {
a {
color: blue;
background-color: red;
}
font-family: Arial;
font-size: 20px;
font-weight: bold;
color: #ff0000;
padding: 4px;
margin-top: 10px;
}
@mixin布尔写法
条件编译中的用法:我们可以在条件编译中使用布尔值。请看下面的例子,我们在 mixin 中传递了一个真值,这样@if 块将被编译。
@mixin button-format( $round-button, $size ) {
color: white;
background-color: blue;
width: $size;
@if $round-button {
height: $size;
border-radius: $size / 2;
}
}
.mybutton {
@include button-format(true, 100px);
}
编译后的 CSS 文件:
.mybutton {
color: white;
background-color: blue;
width: 100px;
height: 100px;
border-radius: 50px;
}
继承
@extend继承的基本使用
在原生CSS中,我们总是将多个相关类中相同的样式提取出来形成一个基本类,比如下面代码中.btn样式类就是.btn-success、.btn-danger的基本样式类,.btn-success、.btn-danger使用时必须搭配.btn
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.btn {
display: inline-block;
padding: 6px 12px;
font-size: 14px;
font-weight: 400;
line-height: 1.5em;
text-align: center;
vertical-align: middle;
cursor: pointer;
border: 1px solid transparent;
border-radius: 4px;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
border-color: #5cb85c;
}
.btn-danger {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
</style>
</head>
<body>
<a class="btn btn-success">成功</a>
<a class="btn btn-danger">失败</a>
</body>
</html>
当然,为了使用简单而言,上面样式定义可以更改为
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.btn, .btn-success, .btn-danger {
display: inline-block;
padding: 6px 12px;
font-size: 14px;
font-weight: 400;
line-height: 1.5em;
text-align: center;
vertical-align: middle;
cursor: pointer;
border: 1px solid transparent;
border-radius: 4px;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
border-color: #5cb85c;
}
.btn-danger {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
</style>
</head>
<body>
<a class="btn-success">成功</a>
<a class="btn-danger">失败</a>
</body>
</html>
这样在使用时,.btn-success、.btn-danger就可以单独使用了。
而在SCSS中,.btn-success、.btn-danger就是继承.btn的公共基础样式,语法如下:
.btn {
display: inline-block;
padding: 6px 12px;
font-size: 14px;
font-weight: 400;
line-height: 1.5em;
text-align: center;
vertical-align: middle;
cursor: pointer;
border: 1px solid transparent;
border-radius: 4px;
}
.btn-success {
@extend .btn;
color: #fff;
background-color: #5cb85c;
border-color: #5cb85c;
}
.btn-danger {
@extend .btn;
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
可以发现,编译结果和预期一致。
占位符 %
.btn, .btn-danger, .btn-success {
display: inline-block;
padding: 6px 12px;
font-size: 14px;
font-weight: 400;
line-height: 1.5em;
text-align: center;
vertical-align: middle;
cursor: pointer;
border: 1px solid transparent;
border-radius: 4px;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
border-color: #5cb85c;
}
.btn-danger {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
上面CSS代码中,其实还有优化的空间,那就是.btn定义显得可有可无了,也就是说,不定义.btn,最终效果也一致。
.btn-danger, .btn-success {
display: inline-block;
padding: 6px 12px;
font-size: 14px;
font-weight: 400;
line-height: 1.5em;
text-align: center;
vertical-align: middle;
cursor: pointer;
border: 1px solid transparent;
border-radius: 4px;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
border-color: #5cb85c;
}
.btn-danger {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
而在SCSS中,我们可以使用占位符%,来定义公共基础样式,而占位符选择器不会被编译到CSS中
%btn {
display: inline-block;
padding: 6px 12px;
font-size: 14px;
font-weight: 400;
line-height: 1.5em;
text-align: center;
vertical-align: middle;
cursor: pointer;
border: 1px solid transparent;
border-radius: 4px;
}
.btn-success {
@extend %btn;
color: #fff;
background-color: #5cb85c;
border-color: #5cb85c;
}
.btn-danger {
@extend %btn;
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
占位符继承,相当于将占位符替换为继承类,比如.btn-success中@extend %btn,相当于将%btn类替换为.btn-success类,比如下面代码
多继承
一个选择器中可以继承多个公共基础样式,即一个选择器中可以多次@extend多个样式类
对比SCSS和CSS来看,SCSS继承语法的语义更加明确,而CSS的语义就略显单薄。
继承和混入的区别
继承的是多个样式共同使用的基础样式,样式内容相同,继承可以避免在多个样式内部书写重复基础样式。
混入的是多个样式共同使用的公共样式,样式属性相同,但是值可能不同,利用混入的传参机制,可以避免在多个样式中书写重复的样式属性。
插槽
插值语法的作用
/ 在原生SCSS默认会被当成分隔符使用,但是当 / 两边中存在变量时,/ 就会被当成除法运算符,这会导致一些问题,如下代码:
我们期望编译结果是:font: 12px/1.5em Arial;
但是实际上,编译报错,因为 $font-size/$line-height 被当成了除法运算,但是除数和被除数的单位不同且无法转化,因此编译报错。
此时,我们可以使用SCSS的插值语法来避免 $font-size/$line-height 中 / 被当成除号
插值语法即 #{},插值语法可以将变量当成普通字符串输出。
插值语法的使用
插值语法可以在如下地方使用:
- 选择器名
- 属性名
- 属性值
- 注释
需要注意的是,插值语法中使用的变量必须要在使用前定义好,否则会报错