在前端开发中,组织和管理 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>
文章有(1)条网友点评