当我们编写scss代码的时候,我们需要意识到,scss代码会编译成css代码。scss并不能保证css代码的可读性以及可维护性。
选择器的嵌套
和普通的css代码相比,scss允许我们进行选择器的嵌套。这样有利于我们更好的组织代码。
选择器的嵌套可以使代码更加直观,同时也可以将继承关系表现的更加清晰。
main.scss
代码语言:javascript复制// scss-lint:disable ColorKeyword
$link-color:black;
p{
font-size:1em;
a{
color:$link-color;
}
}
编译后
代码语言:javascript复制p{
font-size:1em }
p a {
color:black;}
浏览器使用了html的层级结构去计算css的属性值,仔细想一想,我们写的嵌套的选择器,其实就是这么回事儿。
& 符号代码父元素
在scss中,&
符号代表父选择器。
$link-color:black;
$hover-color:red;
.link{
color:$link-color;
&:hover{
color:$hover-color;
}
}
编译后
代码语言:javascript复制.link{
color:black; }
.link:hover {
color:red; }
多个&符号
&
符号代表父选择器,我们也可以使用多个&
符号。
main.scss
代码语言:javascript复制.link{
&, .&-small{
color:blue;
}
}
编译后
代码语言:javascript复制.link, .link-small{
color:blue; }
&符号可以出现多次,所以我们不必每次都写父选择器的名字。
& 操作符修改选择器顺序
直接看个例子:
代码语言:javascript复制// scss-lint:disable colorkeyword
$normal-color:red;
$home-color:orange;
.normal{
color:$normal-color;
.home & {
color:$home-color;
}
}
编译后
代码语言:javascript复制.normal{
color:red;}
.home .normal{
color:orange;}
我们发现,原先写在normal中的home跑到了normal之前。
@extend 指令
如果一些样式需要用到的地方很多,我们可以使用@extend指令将它们进行合并。
看个列子:
代码语言:javascript复制$default-color:red;
$warning-color:orange;
.button{
display:inline-block;
margin-bottom:0;
font-weight:bold;
text-align:center;
}
.button-default{
background-color:$default-color;
}
.button-alert{
background-color:$warning-color;
}
按钮都有相同的属性,我们就可以这样写:
代码语言:javascript复制$default-color:red;
$warning-color:orange;
.button{
display:inline-block;
margin-bottom:0;
font-weight:bold;
text-align:center;
}
.button-default{
@extend .button;
background-color:$default-color;
}
.button-alert{
@extend .button;
background-color:$warning-color;
}
编译后的内容我就不展示了。
占位符选择器和@extend指令
占位符选择器可以让我创建能够继承的选择器。
代码语言:javascript复制$default-color:red;
$warning-color:orange;
%button{
display:inline-block;
margin-bottom:0;
font-weight:bold;
text-align:center;
}
.button-default{
@extend %button;
background-color:$default-color;
}
.button-alert{
@extend %button;
background-color:$warning-color;
}
效果和上面的一样。
占位符选择器和常用的类选择器以及ID选择器除了是以百分号%开头之外,没有其他区别。
@extend指令 和 @media指令
用下面的代码举个例子:
代码语言:javascript复制$print-color:red;
@media print {
.text {
color: $print-color;
}
}
h1 {
@extend .text;
}
@media print {
h2 {
@extend h1;
}
}
编译后
代码语言:javascript复制@media print {
.text, h1, h2 {
color: red; } }
这时候编译起来是正常的,但是如果我们在@media之外的h1中加入它自己的属性,比如
代码语言:javascript复制h1 {
@extend .text;
border:2px solid #ddd;
}
这时候进行编译,就会报错。
You may not @extend an outer selector from within @media. You may only @extend selectors within the same directive. From "@extend h1" on line 15 of sass/media.scss. on line 8 of sass/media.scss
这是因为在scss中,我们无法继承包裹在@media中的属性,相同的,@media中的选择器也无法继承不被@media包裹的选择器的属性。
@at-root 指令
@at-root用来将嵌套在父元素内部的选择器移到外部。
比如”
代码语言:javascript复制$form-text-color:black;
$form-header-color:orange;
form {
color:$form-text-color;
@at-root .form-header{
color:$form-header-color;
}
}
编译后:
代码语言:javascript复制form {
color:black;
}
.form-header{
color:orange;
}
@at-root 的使用案例并不多见。有些人建议用它来处理动画:
代码语言:javascript复制.box {
animation:blink 5s infinite;
}
@at-root {
@keyframes blink {
0% {opacity: 0;}
100% {opacity: 1;}
}
}
避免过度嵌套
为了让我们的css代码重用性更好,我们需要尽量的做到模块儿化,同时需要尽量减少sass的嵌套层数。因为sass-lint检查到嵌套层数超过3层就会提示报错。
多层级的嵌套一方面在渲染时可能会消耗一定的性能,即影响sass的编译速度,也影响界面的渲染速度。同时也难于我们进行维护,假如我们想要重用嵌套的选择器,我们需要想一些别的方法,甚至只能复制粘贴。