SCSS:样式嵌套

  1. 为什么需要SCSS嵌套
  2. 如何把SCSS 嵌套转换成原生 CSS

**SCSS 嵌套:**SCSS 允许你将 CSS 选择器像 HTML 结构一样嵌套书写,使样式代码的结构与 DOM 结构保持一致,提高可读性和可维护性。

为什么需要SCSS嵌套

假设你要写一个用户信息卡片,HTML 结构如下(这是典型的组件结构):

<div class="user-card">
  <div class="avatar">
    <img src="user.jpg" alt="头像">
  </div>
  <div class="info">
    <h3 class="name">张三</h3>
    <p class="role">前端工程师</p>
    <div class="actions">
      <button class="btn btn-message">发消息</button>
      <button class="btn btn-follow">关注</button>
    </div>
  </div>
</div>

方式一:纯原生 CSS(无嵌套)

/* styles.css */
.user-card {
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 16px;
  display: flex;
  gap: 12px;
}

.user-card .avatar img {
  width: 60px;
  height: 60px;
  border-radius: 50%;
}

.user-card .info {
  flex: 1;
}

.user-card .info .name {
  margin: 0 0 4px 0;
  font-size: 18px;
  color: #333;
}

.user-card .info .role {
  margin: 0 0 10px 0;
  color: #777;
  font-size: 14px;
}

.user-card .info .actions {
  display: flex;
  gap: 8px;
}

.user-card .info .actions .btn {
  padding: 6px 12px;
  border: none;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
}

.user-card .info .actions .btn-message {
  background: #007AFF;
  color: white;
}

.user-card .info .actions .btn-follow {
  background: #eee;
  color: #333;
}

方式二:SCSS 嵌套

// user-card.scss(完全不用 &)
.user-card {
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 16px;
  display: flex;
  gap: 12px;

  .avatar {
    img {
      width: 60px;
      height: 60px;
      border-radius: 50%;
    }
  }

  .info {
    flex: 1;

    .name {
      margin: 0 0 4px 0;
      font-size: 18px;
      color: #333;
    }

    .role {
      margin: 0 0 10px 0;
      color: #777;
      font-size: 14px;
    }

    .actions {
      display: flex;
      gap: 8px;

      .message-btn {
        padding: 6px 12px;
        background: #007AFF;
        color: white;
        border: none;
        border-radius: 4px;
        font-size: 14px;
        cursor: pointer;
      }

      .follow-btn {
        padding: 6px 12px;
        background: #eee;
        color: #333;
        border: none;
        border-radius: 4px;
        font-size: 14px;
        cursor: pointer;
      }
    }
  }
}

SCSS 嵌套的优势

优势 说明
1. 结构对齐 HTML SCSS 的缩进层级 = HTML 的嵌套层级,一眼看懂“谁是谁的孩子”
2. 减少重复 不用手写 .user-card .info .actions .xxx 每次都从头开始
3. 易于维护 要修改 .info 相关样式?直接找到 .info { ... } 块即可
4. 安全作用域 所有样式都限定在 .user-card 内,不会意外影响其他组件
5. 重构方便 如果要把 .user-card 改名为 .member-card,只需改一行

如何把SCSS 嵌套转换成原生 CSS

SCSS 的嵌套 不是 CSS 属性的继承(inheritance),而是 选择器的自动拼接(selector concatenation)

关于选择器的内容,请参考:HTML、CSS和JS的入门:选择器(Selectors)

SCSS 代码(使用嵌套):

.btn-group {
  display: flex;
  gap: 8px;

  .btn {
    padding: 6px 12px;
    border: 1px solid #ccc;
    background: white;

    .icon {
      margin-right: 4px;
    }
  }
}

拼接规则(核心逻辑):每进入一层嵌套,就把外层的选择器 + 空格 + 当前选择器,作为新的完整选择器。

SCSS 嵌套层级 拼接过程 最终 CSS 选择器
.btn-group 最外层,直接使用 .btn-group
.btn(在 .btn-group 内) .btn-group + 空格 + .btn .btn-group .btn
.icon(在 .btn 内,而 .btn.btn-group 内) .btn-group + 空格 + .btn + 空格 + .icon .btn-group .btn .icon

编译后的原生 CSS:

.btn-group {
  display: flex;
  gap: 8px;
}

.btn-group .btn {
  padding: 6px 12px;
  border: 1px solid #ccc;
  background: white;
}

.btn-group .btn .icon {
  margin-right: 4px;
}

.btn-group .btn {...}“选中所有 class 为 btn 的元素,但前提是:这个 btn 必须位于某个 class 为 btn-group 的元素内部(可以是直接子元素,也可以是更深层的后代)。”

.btn-group .btn 被称为 后代选择器(descendant selector)

×

喜欢就点赞,疼爱就打赏