一、BEM基础介绍
定义:BEM(Block Element Modifier)是由Yandex团队提出的前端CSS类名命名方法论,通过块、元素、修饰符三部分构建清晰的组件结构,是现代前端开发中广泛采用的CSS模块化方案。
核心价值:提升CSS代码可维护性、避免样式冲突、支持组件复用,尤其适配中大型前端项目。
基础标识:双下划线__连接块与元素,双连字符--表示修饰符,示例:.menu__item--active。
二、BEM核心概念
| 组成部分 |
描述 |
示例 |
核心作用 |
| Block(块) |
独立且有意义的组件 |
.header、.menu、.card |
表示可独立复用的基础组件 |
| Element(元素) |
块的组成部分 |
.menu__item、.card__title |
块的从属部分,无法独立存在 |
| Modifier(修饰符) |
块/元素的状态/变体 |
.menu--vertical、.card__button--disabled |
表示组件的不同状态或样式变体 |
三、命名语法规则
1. 基本语法结构
1 2 3 4 5 6 7 8 9
|
.block {}
.block__element {}
.block--modifier {}
.block__element--modifier {}
|
2. 分隔符说明
四、BEM命名核心原则
1. 块(Block)的独立性
2. 元素(Element)的从属性
3. 修饰符(Modifier)的可选性
五、完整代码示例
1. HTML结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
<form class="search-form"> <input class="search-form__input" type="text" placeholder="搜索..."> <button class="search-form__button search-form__button--primary" type="submit">搜索</button> <button class="search-form__button search-form__button--secondary" type="reset">重置</button> </form>
<div class="card card--featured"> <img class="card__image" src="image.jpg" alt="示例"> <h3 class="card__title">特荐产品</h3> <p class="card__description card__description--truncated">这是一个很长的描述文本,会被截断显示...</p> <button class="card__button">了解更多</button> </div>
|
2. 对应CSS样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
.search-form { display: flex; gap: 10px; padding: 20px; background: #f5f5f5; }
.search-form__input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; } .search-form__button { padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; }
.search-form__button--primary { background-color: #007bff; color: white; } .search-form__button--secondary { background-color: #6c757d; color: white; }
.card { border: 1px solid #e0e0e0; border-radius: 8px; padding: 20px; max-width: 300px; }
.card--featured { border-color: #007bff; box-shadow: 0 4px 12px rgba(0, 123, 255, 0.2); }
.card__title { font-size: 1.5rem; margin-bottom: 10px; color: #333; } .card__description { color: #666; line-height: 1.5; } .card__button { margin-top: 15px; padding: 8px 16px; background-color: #28a745; color: white; border: none; border-radius: 4px; }
.card__description--truncated { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
|
六、实际项目应用场景
1. 导航菜单
1 2 3 4 5 6 7 8 9 10
| <nav class="nav"> <ul class="nav__list"> <li class="nav__item"><a class="nav__link nav__link--active" href="#">首页</a></li> <li class="nav__item nav__item--dropdown"> <a class="nav__link" href="#">服务</a> <ul class="nav__submenu"><li class="nav__subitem"><a class="nav__sublink" href="#">设计</a></li></ul> </li> </ul> </nav>
|
2. 表单控件(带错误状态)
1 2 3 4 5 6
| <div class="form-field"> <label class="form-field__label" for="email">邮箱</label> <input class="form-field__input form-field__input--error" id="email" type="email"> <div class="form-field__error-message">请输入有效的邮箱地址</div> </div>
|
3. 响应式修饰符
1 2 3 4 5 6
|
.menu__item--hidden-mobile { display: none; } @media (min-width: 768px) { .menu__item--hidden-mobile { display: block; } }
|
七、BEM的常见变体
1. BEM + Sass/SCSS(推荐)
利用Sass嵌套语法简化书写,通过&引用父选择器,保持代码层级清晰:
1 2 3 4 5 6 7 8 9 10 11 12 13
| .menu { display: flex; &__list { list-style: none; } &__item { margin-right: 20px; &--active { font-weight: bold; } } &__link { color: #333; &:hover { color: #007bff; } } }
|
2. 命名空间变体
为类名添加前缀,区分组件类型,提升可读性:
1 2 3 4 5
| .c-card {} .l-header {} .u-text-center {} .js-modal {}
|
3. 更严格的BEM
避免元素嵌套式命名,采用扁平结构,防止类名过长:
1 2 3 4 5
|
.block__element2-child {}
.block__element2__child {}
|
八、BEM的优缺点
优点
结构清晰:直观体现HTML与CSS的对应关系,易读易维护;
避免冲突:每个类名都有独立命名空间,解决样式污染问题;
减少嵌套:仅需一层选择器,降低CSS选择器特异性,提升渲染性能;
便于协作:统一命名规范,减少团队沟通成本;
模块化:组件可独立开发、测试和复用,适配工程化开发。
缺点
- 类名长度偏长,纯手写时稍显繁琐(可通过Sass/PostCSS工具优化)。
九、使用注意事项
避免过度使用:简单项目/小组件无需完整BEM,避免冗余;
坚持语义化命名:根据功能命名,而非样式,示例:用.box__status--error代替.box__red;
控制类名长度:若类名过长,需重新设计组件结构,拆分独立块;
兼容其他方案:可与CSS-in-JS、Bootstrap等框架结合使用,用于自定义组件;
修饰符必配合基础类:不可单独写.button--primary,需与.button配合。
十、BEM与其他CSS命名方法对比
| 方法 |
核心理念 |
优点 |
缺点 |
| BEM |
块-元素-修饰符 |
结构清晰,避免冲突,易协作 |
类名较长 |
| OOCSS |
对象化CSS |
高度复用,分离结构与皮肤 |
需抽象思维,对初学者不友好 |
| SMACSS |
可扩展模块化架构 |
分类清晰,适配大型项目 |
规则较多,配置繁琐 |
| ITCSS |
倒三角CSS |
层次分明,精准控制选择器特异性 |
学习曲线较陡 |
| Atomic CSS |
原子化CSS |
极致复用,样式文件体积小 |
类名无语义,可读性差 |
十一、学习与实践建议
从简入手:先在单个小组件(如按钮、卡片)上实践,再逐步推广到整个项目;
团队统一规范:约定分隔符、命名空间、多单词连接方式,保持项目内一致性;
结合工具:使用Sass/SCSS嵌套、PostCSS插件简化BEM书写,提升效率;
文档化:为复杂组件编写BEM结构文档,方便团队查阅和维护;
灵活适配:根据项目规模调整BEM严格程度,无需生搬硬套规则。