第一百零二期:scss中的选择器

·  阅读 41

这里记录工作中遇到的技术点,以及自己对生活的一些思考,周三或周五发布。

封面图

当我们编写scss代码的时候,我们需要意识到,scss代码会编译成css代码。scss并不能保证css代码的可读性以及可维护性。

选择器的嵌套

和普通的css代码相比,scss允许我们进行选择器的嵌套。这样有利于我们更好的组织代码。

选择器的嵌套可以使代码更加直观,同时也可以将继承关系表现的更加清晰。

main.scss

// scss-lint:disable ColorKeyword

$link-color:black;
p{
  font-size:1em;
  a{
    color:$link-color;
  }
}
复制代码

编译后

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;
  }
}
复制代码

编译后

.link{
  color:black; }
  .link:hover {
    color:red; }
复制代码

多个&符号

&符号代表父选择器,我们也可以使用多个&符号。

main.scss

.link{
  &, .&-small{
    color:blue;
  }
}
复制代码

编译后

.link, .link-small{
  color:blue; }
复制代码

&符号可以出现多次,所以我们不必每次都写父选择器的名字。

& 操作符修改选择器顺序

直接看个例子:

// scss-lint:disable colorkeyword

$normal-color:red;
$home-color:orange;
.normal{
  color:$normal-color;
  .home & {
    color:$home-color;
  }
}
复制代码

编译后

.normal{
  color:red;}
.home .normal{
  color:orange;}
复制代码

我们发现,原先写在normal中的home跑到了normal之前。

@extend 指令

如果一些样式需要用到的地方很多,我们可以使用@extend指令将它们进行合并。

看个列子:

$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;
}
复制代码

按钮都有相同的属性,我们就可以这样写:

$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指令

占位符选择器可以让我创建能够继承的选择器。

$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指令

用下面的代码举个例子:

$print-color:red;
@media print {
    .text {
        color: $print-color;
    }
}

h1 {
    @extend .text;
}

@media print {
    h2 {
        @extend h1;
    }
}
复制代码

编译后

@media print {
  .text, h1, h2 {
    color: red; } }
复制代码

这时候编译起来是正常的,但是如果我们在@media之外的h1中加入它自己的属性,比如

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用来将嵌套在父元素内部的选择器移到外部。

比如”

$form-text-color:black;
$form-header-color:orange;
form {
  color:$form-text-color;
  @at-root .form-header{
    color:$form-header-color;
  }
}
复制代码

编译后:

form {
  color:black;
}
.form-header{
  color:orange;
}
复制代码

@at-root 的使用案例并不多见。有些人建议用它来处理动画:

.box {
  animation:blink 5s infinite;
}
@at-root {
  @keyframes blink {
    0% {opacity: 0;}
    100% {opacity: 1;}
  }
}
复制代码

避免过度嵌套

为了让我们的css代码重用性更好,我们需要尽量的做到模块儿化,同时需要尽量减少sass的嵌套层数。因为sass-lint检查到嵌套层数超过3层就会提示报错。

多层级的嵌套一方面在渲染时可能会消耗一定的性能,即影响sass的编译速度,也影响界面的渲染速度。同时也难于我们进行维护,假如我们想要重用嵌套的选择器,我们需要想一些别的方法,甚至只能复制粘贴。

最后

  • 公众号《JavaScript高级程序设计》
  • 公众号内回复”vue-router“ 或 ”router“即可收到 VueRouter源码分析的文档。
  • 回复”vuex“ 或 ”Vuex“即可收到 Vuex 源码分析的文档。

全文完,如果喜欢。

请点赞和"在看"吧,最好也加个"关注",或者分享到朋友圈。

分类:
前端
分类:
前端
收藏成功!
已添加到「」, 点击更改