在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. 最佳实践
-
命名语义化
✅
.search-form__input
❌
.left-col__textbox
-
SCSS嵌套不超过3层
scss.block { &__elem1 { &__elem2 { /* 尽量避免 */ } } }
-
修饰符独立于元素
scss.block--modifier { /* 块级修饰符 */ } .block__elem--modifier { /* 元素修饰符 */ }
-
与工具类结合
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的工具类,构建高可维护的前端样式体系。