BEM规范:构建可维护的CSS
在现代Web开发中,CSS是我们实现网页样式的关键工具之一。然而,随着项目的复杂性增加,CSS代码的可维护性成为一个挑战。为了解决这个问题,BEM(Block, Element, Modifier)规范应运而生。
一、什么是BEM?
BEM是一种命名约定,旨在使CSS代码具有更好的可读性和可维护性。它由三个基本部分组成:
- 块(Block):块是页面上具有独立功能的可重用组件。可以将块视为页面上的一个模块,它可以包含其他块或元素。块的类名以一个描述性词汇作为前缀,使用连字符进行连接,例如:.block。
- 元素(Element):元素是块的组成部分,它们不能独立存在,并且具有与块相关的语义。元素的类名由块的类名作为前缀,使用双下划线连接,例如:.block__element。
- 修饰符(Modifier):修饰符用于改变块或元素的外观、状态或行为。修饰符的类名由块或元素的类名作为前缀,使用双短横线连接,例如:.block–modifier或.block__element–modifier。
二、为什么要使用BEM?
使用BEM规范有以下几个优点:
- 可读性强:通过使用清晰的命名约定,代码的含义更加明确和直观。任何人都能轻松理解样式规则所针对的目标元素。
- 可维护性好:BEM提供了一种结构化的方式来组织CSS代码,使其易于扩展和维护。每个块、元素和修饰符都有自己的作用范围和含义,避免了全局样式的混乱。
- 重用性高:块和元素可以在不同的场景中重复使用,促进了代码的可重用性和模块化
- 避免选择器冲突:通过将块和元素的类名限制在其父级作用域内,BEM规范有效地避免了选择器冲突的问题。
示例
<div class="product-list">
<div class="product-list__item">
<h3 class="product-list__title">商品标题</h3>
<p class="product-list__description">商品描述</p>
</div>
<div class="product-list__item product-list__item--highlighted">
<h3 class="product-list__title">特殊商品标题</h3>
<p class="product-list__description">特殊商品描述</p>
</div>
<div class="product-list__item product-list__item--on-sale">
<h3 class="product-list__title">促销商品标题</h3>
<p class="product-list__description">促销商品描述</p>
</div>
<div class="product-list__item product-list__item--new">
<h3 class="product-list__title">新品标题</h3>
<p class="product-list__description">新品描述</p>
</div>
</div>
在上述示例中,.product-list代表整个商品列表块,而.product-list__item则表示商品列表块内的每个商品元素。我们使用双下划线来连接块与元素的类名。此外,我们还添加了修饰符类名来表示特殊商品(.product-list__item–highlighted)、促销商品(.product-list__item–on-sale)和新品(.product-list__item–new)。
接下来,我们可以编写CSS规则来定义这些类名对应的样式:
.product-list {
/* 商品列表块的样式规则 */
}
.product-list__item {
/* 商品列表块内商品元素的样式规则 */
}
.product-list__item--highlighted {
/* 特殊商品的样式规则 */
}
.product-list__item--on-sale {
/* 促销商品的样式规则 */
}
.product-list__item--new {
/* 新品的样式规则 */
}
三、在vue3中的应用
- 在bem.scss文件中封装bem规则
$namespace:"product" !default;
$block:"-" !default;
$element:'__' !default;
$modifier:'--' !default;
// .product-list
@mixin b($b) {
$B:#{$namespace + $block + $b};
.#{$B}{
@content
}
}
// .product-list__item
@mixin e($e) {
$selector:&;
$E:#{$selector + $element + $e};
@at-root{
#{$E}{
@content
}
}
}
// .product-list__item--highlighted
@mixin m($m) {
$selector:&;
$M:#{$selector + $modifier + $m};
@at-root{
#{$M}{
@content
}
}
}
- 在
vite.config.ts
中添加预处理scss样式
import path from "path";
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "./src/style/bem.scss";`,
},
},
},
resolve: {
alias: [
{
find: "@/",
replacement: path.resolve(process.cwd(), "src") + "/",
},
],
},
});
- 组件中使用示例
<template>
<div class="product-list">
<div class="product-list__item">
<h3 class="product-list__title">商品标题</h3>
<p class="product-list__description">商品描述</p>
</div>
<div class="product-list__item product-list__item--highlighted">
<h3 class="product-list__title">特殊商品标题</h3>
<p class="product-list__description">特殊商品描述</p>
</div>
<div class="product-list__item product-list__item--on-sale">
<h3 class="product-list__title">促销商品标题</h3>
<p class="product-list__description">促销商品描述</p>
</div>
<div class="product-list__item product-list__item--new">
<h3 class="product-list__title">新品标题</h3>
<p class="product-list__description">新品描述</p>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from "vue";
</script>
<style scoped lang="scss">
@include b("list") {
/* 商品列表块的样式规则 */
@include e("item") {
/* 商品列表块内商品元素的样式规则 */
@include m("highlighted") {
/* 特殊商品的样式规则 */
}
}
}
</style>
四、总结
BEM规范是一种有助于构建可维护CSS代码的强大工具。通过明确的命名约定和结构化的代码组织,BEM使得代码更易读、扩展和维护。无论是个人项目还是团队开发,采用BEM规范都能提高CSS开发效率和代码质量。让我们学习并应用BEM规范,为我们的CSS代码注入更多的可维护性