深色模式
项目做大了,CSS 命名开始混乱:.title、.list-item、.active……全局样式冲突越来越多。用 BEM 规范统一命名之后,问题少了很多。
BEM 是什么
BEM = Block(块)、Element(元素)、Modifier(修饰符)
Block(块):独立的组件,如 header、menu、card
Element(元素):块的组成部分,用 __ 连接,如 card__title、menu__item
Modifier(修饰符):块或元素的状态/变体,用 -- 连接,如 card--dark、menu__item--active命名格式
css
/* Block */
.card {
}
/* Element(属于 card 的子元素)*/
.card__title {
}
.card__content {
}
.card__footer {
}
/* Modifier(card 的变体)*/
.card--dark {
}
.card--horizontal {
}
/* Element + Modifier */
.card__title--large {
}实际例子
html
<!-- 商品卡片 -->
<div class="product-card product-card--featured">
<img class="product-card__image" src="..." />
<div class="product-card__body">
<h3 class="product-card__title">商品名称</h3>
<p class="product-card__price">¥99</p>
<p class="product-card__price product-card__price--original">¥199</p>
</div>
<div class="product-card__footer">
<button class="product-card__btn product-card__btn--primary">
加入购物车
</button>
<button class="product-card__btn product-card__btn--secondary">收藏</button>
</div>
</div>css
.product-card {
border: 1px solid #eee;
border-radius: 8px;
overflow: hidden;
}
/* Modifier:特色商品 */
.product-card--featured {
border-color: #f90;
box-shadow: 0 2px 8px rgba(255, 153, 0, 0.3);
}
.product-card__image {
width: 100%;
height: 200px;
object-fit: cover;
}
.product-card__price {
color: #f40;
font-size: 18px;
font-weight: bold;
}
/* 原价(划线)*/
.product-card__price--original {
color: #999;
font-size: 14px;
text-decoration: line-through;
}用 SCSS 写 BEM
scss
.product-card {
border: 1px solid #eee;
// &-- 生成 Modifier
&--featured {
border-color: #f90;
}
// &__ 生成 Element
&__image {
width: 100%;
}
&__price {
color: #f40;
// Element 的 Modifier
&--original {
color: #999;
text-decoration: line-through;
}
}
}BEM 的好处
1. 命名自解释:看类名就知道这个元素是什么、属于哪里
2. 低优先级:只用类选择器,不用嵌套,样式权重一致
3. 可复用:Block 是独立的,可以放到任何地方
4. 低耦合:不依赖 HTML 结构,重构不怕不适合用 BEM 的地方
- 工具类(如 .text-center、.mt-16)不用 BEM
- 状态类(如 .is-active、.has-error)习惯用 is-/has- 前缀
- 全局重置样式和 Vue scoped 配合
vue
<style scoped>
/* scoped 已经有了隔离,可以适当简化 BEM */
/* 不需要写完整的 block 名,因为 scoped 已经加了哈希 */
.card {
}
.card__title {
}
.card--dark {
}
</style>小结
block__element--modifier三层命名- 只用类选择器,不嵌套,保持低优先级
- SCSS
&__和&--让 BEM 更方便写 - 状态类用
.is-active、.has-error前缀