在前端开发中,组织和管理 CSS 样式是一个常见的挑战。BEM(Block Element Modifier)架构作为一种解决方案,通过一种清晰且易于维护的方式来组织样式代码。它将样式分解为独立的块(Blocks)、元素(Elements)和修饰符(Modifiers),为团队合作和大型项目提供了一致性和可扩展性。然而,随着项目规模的增长和需求的变化,我们需要更灵活和高效的方式来管理样式,这就引入了 Sass(Syntactically Awesome Stylesheets)。Sass 是一种 CSS 预处理器,它为我们提供了许多强大的工具,如变量、嵌套、混合、继承等,使我们能够更加高效地编写和组织 CSS 代码。本文将深入探讨 BEM 架构的原理及其在实际项目中的应用,并结合 Sass 的强大功能,展示如何通过 Sass 实现 BEM 架构,从而使我们的样式代码更具可维护性、可扩展性和重用性。
1.BEM架构概念
Block(块):Block 是一个独立的、可复用的组件或模块,它代表一个完整的功能单元。块是一个顶层的元素,它本身应该有意义并且可以独立存在。
Element(元素):Element 是块的组成部分,它不能单独存在,必须依赖于块。Element 是块的一部分,它只有在块的上下文中才有意义。
Modifier(修饰符):Modifier 是用于改变块或元素外观、状态或行为的标志。通过添加修饰符类名,可以修改块或元素的样式,从而实现不同的变体。
下面以 Element 组件库为例,感受 BEM 架构的用法与规范:

其中 el-tag 代表一个完整的功能单元块,是一个顶层的元素。
el-tag–primary 表示一个修饰符类,primary 代表样式类型。
el-tag__content 表示的是功能单元块下面的一个子类。
由此,BEM 架构约定的命名规范一般为:namespace-block__element–modifier
2.Sass相关
要使用 Sass 来实现 BEM 架构,首先要先对 Sass 的常见语法以及功能有一定的了解。主要涉及有 Sass 的嵌套规则、父选择器、变量、插值语法、混合等。
实现代码如下:
// src/assets/styles/common.scss
// !default 表示这个变量如果没有赋过别的值,默认为 mx(element中为el,可以更换为自己特有的前缀)
$namespace: 'mx' !default; // 创建一个命名空间,用于定义规范类名的开头
$block-sel: '-' !default; // 创建一个连接,用于连接块名
$element-sel: '__' !default; // 创建一个连接,用于连接元素名
$modify-sel: '--' !default; // 创建一个连接,用于连接标识名
// 创建一个定义 b 的混入,可以生成例如 .mx-bn 的样式
@mixin b($bn) {
$name: $namespace + $block-sel + $bn;
.#{$name} { // 插值语法 即 name 的值
@content; // 相当于一个占位符
}
}
// 创建一个定义 e 的混入,可以生成例如 .mx-bn__en 的样式
@mixin e($en) {
$parent: &; // 获取父级的类名 这里获取的是 .mx-bn
// @at-root 可以让以下类名的样式跳出父级包裹,例如 .mx-bn .mx-bn__en{} 去除多余的父级选择器变为 .mx-bn__en{}
@at-root {
#{$parent + $element-sel + $en} {
@content;
}
}
}
// 创建一个定义 m 的混入,可以生成例如 .mx-bn--mn 的样式
@mixin m($mn) {
$parent: &;
@at-root {
#{$parent + $modify-sel + $mn} {
@content;
}
}
}
3.Vite相关配置
这里以 Vue3 + Vite 项目为例,要将 common.scss 配置为全局通用样式,需要在 vite.config.ts 或 vite.config.js文件中添加 css 配置选项:
export default defineConfig({
plugins: [vue()],
css:{
preprocessorOptions:{
scss:{
additionalData:`@import "@/assets/styles/common.scss";`
}
}
}
})
4.BEM架构在项目中的使用
<template>
<div class="mx-login">
<p class="mx-login__title">账号登录</p>
<button class="mx-login--blue">登录</button>
</div>
</template>
<script lang="ts" setup>
</script>
<style lang="scss">
@include b(login) { // 对应 mx-login
height: 300px;
width: 500px;
display: flex;
flex-direction: column;
align-items: center;
background-color: #eee;
@include e(title) { // 对应 mx-login__title
font-size: 20px;
font-weight: 600;
}
@include m(blue) { // 对应 mx-login--blue
background-color: blue;
}
}
</style>







文章有(13)条网友点评
sildenafil dog dosage
sildenafil dog dosage
xenical nome generico
xenical nome generico
hims tadalafil daily
hims tadalafil daily
viagra allergic reactions
viagra allergic reactions
tadalafil starting dose
tadalafil starting dose
vidalista tadalafil 10mg
vidalista tadalafil 10mg
cyclosporine 100mg capsules
cyclosporine 100mg capsules
orlistat alli price
orlistat alli price
orlistat medicine uses
orlistat medicine uses
cipla finpecia reddit
cipla finpecia reddit
cialis stuffy nose
cialis stuffy nose
doxycycline hyclate acne results
doxycycline hyclate acne results