前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Sass速通(二):嵌套与作用域

Sass速通(二):嵌套与作用域

作者头像
lonelydawn
发布2021-09-26 11:35:38
1.4K0
发布2021-09-26 11:35:38
举报

Sass 提供了嵌套的书写方式,用以简化选择器的书写,同时也带来了“作用域”。

嵌套

选择器嵌套

在 Sass 中,可以在父选择器中写子选择器,以嵌套的形式来表达关联的关系,这样做可以减少我们重复书写父选择器的工作量。

代码语言:javascript
复制
#content {
  #article {
    h1 {
      color: red;
    }
    p {
      color: grey;
    }
  }
}

编译后

代码语言:javascript
复制
#content #article h1 {
  color: red;
}
#content #article p {
  color: grey;
}

在编译时,Sass 会递归遍历所有嵌套关系,从最内层选择器开始,逐层在前面加上父选择器

父选择器 &

在 CSS 中,基本选择器分为以下几种:

  • ID 选择器,如 #id
  • 类选择器,如 .class
  • 标签选择器,如 div、p
  • 属性选择器,如 [lang='en']
  • 伪类选择器,如 a:hover、div:first-child
  • 伪元素选择器,如 p::before、p::after

其中,伪类和伪元素选择器需要与别的选择器复合使用,以确定是哪些元素的伪类或伪元素。而其它选择器也可以复合使用,如 div#id、div.class、div[lang='en'] 等。

Sass 为了在嵌套中更好地表达这些复合关系,提供了父选择器 &。

代码语言:javascript
复制
div {
  content: '#{&}';      // 将 & 当做变量使用
  &#app { color: green; }
  &.app { color: blue; }
  &:hover { color: red; }
  &:first-child { color: grey; }
  &::before { content: ''; }
}

编译后

代码语言:javascript
复制
div { content: "div"; }
div#app  { color: green; }
div.app  { color: blue; }
div:hover  { color: red; }
div:first-child  { color: grey; }
div::before  { content: ''; }

可以看到,如果把 & 当做变量使用,它被编译为了父选择器。 要注意的是,在复合选择器中,& 只能放在开头使用。

群组选择器

在 CSS 中,可以用逗号分隔多个选择器,形成一个群组。元素只要满足群组中任何一个选择器,都会使用群组对应的样式进行渲染,如

代码语言:javascript
复制
a, span, label { 
    color: grey;
}

在 Sass 中,我们可以使用嵌套的形式来简写群组。

代码语言:javascript
复制
.container {
  h1, h2, h3 { margin-bottom: .8em; }
}

nav, aside {
  a { color: blue; }
}

编译后

代码语言:javascript
复制
.container h1, .container h2, .container h3 {
  margin-bottom: .8em;
}
nav a, aside a {
  color: blue;
}
组合选择器 >、+、~

组合选择器:

  • > 为子选择器,如 div > p,选中条件:
    1. 节点为 div 的邻层子节点
    2. 节点标签为 p
  • + 为相邻兄弟选择器,如 div + p,选中条件:
    1. 节点为 div 后面的第一个节点
    2. 节点标签为 p
  • ~ 为同层后续选择器,如 div ~ p,选中条件:
    1. 节点为 div 后面的同层节点
    2. 节点标签为 p

对于组合选择器,直接嵌套就可以了。

代码语言:javascript
复制
article {
  ~ article { border-top: 1px dashed #ccc }
  > section { background: #eee }
  dl > {
    dt { color: #333 }
    dd { color: #555 }
  }
  nav + & { margin-top: 0 }
}

编译后

代码语言:javascript
复制
article ~ article { border-top: 1px dashed #ccc }
article > footer { background: #eee }
article dl > dt { color: #333 }
article dl > dd { color: #555 }
nav + article { margin-top: 0 }

属性嵌套

除了可以嵌套书写选择器,还可以嵌套书写属性,如

代码语言:javascript
复制
nav {
  border: {
  style: solid;
  width: 1px;
  color: #ccc;
  }
}

编译后

代码语言:javascript
复制
nav {
  border-style: solid;
  border-width: 1px;
  border-color: #ccc;
}

作用域

Sass 引入了嵌套,出现了嵌套层级,自然也就有了“层级作用域”。

变量作用域

在 Sass 中,变量只能在它被声明的层级和子层级访问;如果一个变量在不同层级中被重复定义,在使用时会从下到上寻找最近的定义。这与 JS 中的函数作用域相似。

代码语言:javascript
复制
.inner {
  $width: 10px;
  width: $width;
  p {
    width: $width / 2;
  }
}

编译后

代码语言:javascript
复制
.inner { width: 10px; }
.inner p { width: 5px; }

如果变量仅在子级被定义,而在父级被访问,编译时会报错。

代码语言:javascript
复制
Undefined variable: "$width".

@import

@import 是 CSS2 原生支持的指令,由于 CSS 只有在执行到这条指令时,才会去加载对应的文件,这样会导致页面闪烁和加载变慢,所以平时并不常用。

Sass 改进了这条指令,它会在编译时将导入的资源直接替换并插入指令所在的位置

因此,如果 @import 导入的资源位置在嵌套层级中,那么:

  • 资源中的变量只在当前层级中可用
  • 资源中的选择器在编译时会带上父级前缀
代码语言:javascript
复制
// _source.scss
$width: 10px;
p {
    color: red;
    font-size: 14px;
}
代码语言:javascript
复制
// index.scss
@import '_source';
$width: 20px;
.outer {
  width: $width;
  .inner {
    @import '_source';
    width: $width;
  }
}

编译后

代码语言:javascript
复制
p { color: red; font-size: 14px; }

.outer { width: 20px; }
.outer .inner { width: 10px; }
.outer .inner p { color: red; font-size: 14px; }

在使用 @import 导入文件时,可以不写 .scss 或 .sass 后缀。

如果资源是作为专被引用的公共资源,规范的命名方法是在名称前加下划线。

以下几种情况,Sass 会将 @import 编译为原生的 CSS 指令:

  • 资源文件后缀为 .css
  • 资源以 URL 地址的形式导入
  • 资源以 CSS 的 url() 方法导入

@media

@media 是 CSS 原生支持的指令,用于查询设备媒体,以便做响应式布局。

Sass 对 @media 做了一些改进,允许我们在嵌套的过程中书写媒体查询和响应代码。在编译时, Sass 会把媒体查询编译到文件最外层,并为子选择器加上父选择器前缀。

代码语言:javascript
复制
$media-prop: min-width;
$media-middle-width: 1200px;
$media-large-width: 1980px;
.container {
  .left {
    font-size: 12px;
    @media screen and ($media-prop: $media-middle-width) {
      font-size: 14px;
    }
  }
  .right {
    font-size: 14px;
    @media screen {
      @media ($media-prop: $media-middle-width) {
        font-size: 18px;
      }
      @media ($media-prop: $media-large-width) {
        font-size: 22px;
      }
    }
  }
}

编译后

代码语言:javascript
复制
.container .left {
  font-size: 12px;
}
@media screen and (min-width: 1200px) {
  .container .left {
    font-size: 14px;
  }
}
.container .right {
  font-size: 14px;
}
@media screen and (min-width: 1200px) {
  .container .right {
    font-size: 18px;
  }
}
@media screen and (min-width: 1980px) {
  .container .right {
    font-size: 22px;
  }
}

使用 Sass 媒体查询的好处:

  • 以前使用原生 CSS 做响应式布局时,我们需要先写好不同的媒体查询区块,整理出元素在不同设备的特殊样式,然后写入对应的区块。一个元素的样式分散在不同的媒体查询中,维护起来比较麻烦。
  • 在 Sass 中,我们可以在写完一个元素的公共样式之后,直接在下面嵌套媒体查询,所有的响应代码和这个元素都写在同一块地方,维护起来非常方便。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 嵌套
    • 选择器嵌套
      • 父选择器 &
      • 群组选择器
      • 组合选择器 >、+、~
    • 属性嵌套
    • 作用域
      • 变量作用域
        • @import
          • @media
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档