在SCSS中使用BEM命名规范

在SCSS中使用BEM(Block Element Modifier)命名规范可以显著提高代码的可读性和可维护性。 以下是详细的实现方法和最佳实践:


1. BEM核心结构

scss 复制代码
/* Block */
.block { /* 块样式 */ }

/* Element (用双下划线连接) */
.block__element { /* 元素样式 */ }

/* Modifier (用双连字符连接) */
.block--modifier { /* 修饰符样式 */ }

2. SCSS中的BEM实现方式

(1) 基础写法

scss 复制代码
// Block
.card {
  padding: 20px;

  // Element
  &__header {
    font-size: 18px;
  }

  // Modifier
  &--featured {
    border: 2px solid gold;
  }
}

编译结果:

css 复制代码
.card { padding: 20px; }
.card__header { font-size: 18px; }
.card--featured { border: 2px solid gold; }

(2) 嵌套元素的多层级

scss 复制代码
.menu {
  &__item {
    &__icon {
      /* .menu__item__icon (不推荐超过2级) */
    }
  }
}

⚠️ 建议 :避免超过2级嵌套(如.block__elem1__elem2),改用扁平化命名。

(3) 元素修饰符

scss 复制代码
.btn {
  &__icon {
    &--large { /* .btn__icon--large */ }
  }
}

3. 修饰符的独立使用

scss 复制代码
// Block + Modifier(不依赖元素)
.button {
  &--disabled { opacity: 0.5; }
}

// 元素 + Modifier
.form {
  &__input {
    &--error { border-color: red; }
  }
}

4. 状态类(结合SMACSS)

scss 复制代码
// 用 is-/has- 前缀表示动态状态
.tab {
  &.is-active { /* JavaScript触发的状态 */ }
  &.has-error { /* 错误状态 */ }
}

5. SCSS变量 + BEM

scss 复制代码
$block: 'card';
$element: '__header';
$modifier: '--featured';

.#{$block} {
  &#{#{$element}} { color: blue; }
  &#{$modifier} { background: gold; }
}

6. 媒体查询中的BEM

scss 复制代码
.card {
  @media (min-width: 768px) {
    &__title { font-size: 24px; }
  }
}

7. 实战案例

组件:带状态的卡片

scss 复制代码
.card {
  padding: 16px;
  border-radius: 8px;

  &__title {
    font-weight: bold;
    
    &--highlight { color: #ff5722; }
  }

  &__body {
    margin-top: 10px;
  }

  &--dark {
    background: #333;
    color: white;
  }

  &.is-collapsed {
    .card__body { display: none; }
  }
}

对应HTML:

html 复制代码
<div class="card card--dark is-collapsed">
  <h2 class="card__title card__title--highlight">标题</h2>
  <div class="card__body">内容</div>
</div>

8. 避免的常见错误

错误写法 问题 正确写法
.card .title 依赖DOM结构 .card__title
.card--header 修饰符误用于元素 .card__header
.card__btn--red 用颜色命名修饰符 .card__btn--warning

9. 最佳实践

  1. 命名语义化

    .search-form__input

    .left-col__textbox

  2. SCSS嵌套不超过3层

    scss 复制代码
    .block {
      &__elem1 {
        &__elem2 { /* 尽量避免 */ }
      }
    }
  3. 修饰符独立于元素

    scss 复制代码
    .block--modifier { /* 块级修饰符 */ }
    .block__elem--modifier { /* 元素修饰符 */ }
  4. 与工具类结合

    html 复制代码
    <div class="card u-mt-20 is-active">
      <!-- BEM + Utility Classes -->
    </div>

10. 扩展技巧

(1) 占位符选择器(Placeholder)

scss 复制代码
%card-base {
  border-radius: 8px;
}

.card {
  @extend %card-base;
  &--featured {
    @extend %card-base;
    border-width: 2px;
  }
}

(2) Mixin生成BEM类

scss 复制代码
@mixin element($name) {
  &__#{$name} {
    @content;
  }
}

.card {
  @include element('header') {
    font-size: 20px;
  }
}

通过SCSS的嵌套和&符号,BEM规范可以更直观地实现,同时保持CSS输出的整洁性。建议结合SMACSS的状态类和Atomic CSS的工具类,构建高可维护的前端样式体系。

相关推荐
北京_宏哥11 分钟前
《刚刚问世》系列初窥篇-Java+Playwright自动化测试-30- 操作单选和多选按钮 - 番外篇(详细教程)
java·前端·测试
leslie040311 分钟前
从零构建微前端生态平台:基于 Module Federation 的最佳实践
前端
筷子夹豆腐11 分钟前
Vue3 解决大屏自适应(缩放)解决方案
前端
Qinana12 分钟前
🚀 用代码搭建「心情小窝」:一个极简情绪记录工具的实现 📝
前端·javascript
可乐202713 分钟前
为什么监听数据变化 页面才会出现内容
前端
isixe14 分钟前
uniapp 兼容 H5 滚动
前端·vue.js
JarvanMo14 分钟前
🪦 话说……Flutter 真要凉了吗?那些瞎吵吵的背后到底咋回事儿?
前端
张志鹏PHP全栈15 分钟前
Vue3第八天,watch监听函数
前端·vue.js
司宸18 分钟前
学习笔记二
前端
讨厌吃蛋黄酥20 分钟前
#Zustand:轻量级状态管理的革命,告别Context与Reducer的痛点!
前端·javascript·react.js