第九十六期:scss中的选择器

2022-07-15 11:15:19 浏览数 (2)

当我们编写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中,&符号代表父选择器。

代码语言:javascript复制
$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的编译速度,也影响界面的渲染速度。同时也难于我们进行维护,假如我们想要重用嵌套的选择器,我们需要想一些别的方法,甚至只能复制粘贴。

0 人点赞