在前端开发中,命名规范的使用对项目的可维护性、可读性以及扩展性至关重要。本文将介绍 BEM (Block, Element, Modifier) 命名规范,分析一个实际项目的代码片段。
BEM 命名规范
BEM 是一种 CSS 命名方法论,旨在提高代码的可维护性和复用性。通过使用 Block(区块)、Element(子元素)和 Modifier(修饰符),开发者能够更好地管理样式。
- Block(区块) : 页面中的独立功能部分或组件,例如
.page
、.search-bar
、.navigation
等。 - Element(子元素) : Block 的组成部分,与 Block 关联且不能单独存在。例如
.search-bar__input
表示search-bar
这个 Block 的输入框子元素。 - Modifier(修饰符) : 用于表示 Block 或 Element 的不同状态或版本。例如
.navigation__icon--primary
和.navigation__icon--default
分别表示图标的两种不同样式。
命名示例
html
<div class="card">
<div class="card__header">
<h2 class="card__title">卡片标题</h2>
<button class="card__button card__button--primary">主要按钮</button>
</div>
<div class="card__body">
<p class="card__text">这是卡片的主体内容。</p>
</div>
<div class="card__footer">
<a href="#" class="card__link">更多信息</a>
</div>
</div>
-
Block :
.card
是一个块(block),代表整个卡片组件。 -
Element :
.card__header
,.card__title
,.card__button
,.card__body
,.card__text
,.card__footer
,.card__link
是元素(element),它们是卡片块的一部分。 -
Modifier :
.card__button--primary
是修饰符(modifier),用于修改.card__button
的样式。
使用 BEM 命名规范,可以避免样式冲突,并且能够快速理解每个类的作用,提高开发效率。
实战分析
画图分析
现在我们来实战一下高德地图的导航栏,整体为下面这样,我们先看图分析
首先是page
是一个块(block),再把它拆分成两部分:page__head
和page__body
两个元素(element)
接着再把page__head和page__body细分:
-
page__head
- page__head中有search-bar块
- search-bar块中有search-bar__input和search-bar__icon元素
-
page__body
- page__body中有navigation块
- navigation块中有navigation__item元素
- navigation__item元素中又有navigation__icon元素和navigation__text元素
以下是完整的代码示例:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>高铁站页面</title>
<style>
* {
margin: 0;
padding: 0;
outline: 0;
}
body, html {
height: 100%;
-webkit-tap-highlight-color: transparent;
}
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
}
.page {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
overflow-scrolling: touch;
padding: 10px;
background-color: #f9f9f9;
}
.page__header {
padding: 10px;
}
.search-bar {
display: flex;
align-items: center;
height: 40px;
border-radius: 20px;
background-color: #fff;
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1);
}
.search-bar__icon {
display: flex;
align-items: center;
justify-content: center;
padding: 0 10px;
}
.search-bar__icon-image {
width: 20px;
height: 20px;
}
.search-bar__input {
flex-grow: 1;
height: 100%;
border: none;
border-radius: 20px;
padding: 0 10px;
font-size: 16px;
outline: none;
}
.page__body {
display: flex;
justify-content: space-around;
margin-top: 20px;
}
.navigation__item {
text-align: center;
text-decoration: none;
}
.navigation__icon {
width: 50px;
height: 50px;
}
.navigation__text {
margin-top: 5px;
font-size: 14px;
color: #333;
}
</style>
</head>
<body>
<div class="page">
<div class="page__header">
<div class="search-bar">
<span class="search-bar__icon">
<img src="img/sousuo.png" class="search-bar__icon-image">
</span>
<input class="search-bar__input" type="search" placeholder="高铁站">
<a href="#" class="search-bar__icon">
<img src="img/iconfontscan.png" class="search-bar__icon-image">
</a>
<a href="#" class="search-bar__icon">
<img src="img/01.png" class="search-bar__icon-image">
</a>
</div>
</div>
<div class="page__body">
<a href="#" class="navigation__item">
<img src="img/buhang.png" class="navigation__icon">
<div class="navigation__text">步行</div>
</a>
<a href="#" class="navigation__item">
<img src="img/gongjiao.png" class="navigation__icon">
<div class="navigation__text">公交</div>
</a>
<a href="#" class="navigation__item">
<img src="img/a-jiache_huaban1.png" class="navigation__icon">
<div class="navigation__text">驾车</div>
</a>
<a href="#" class="navigation__item">
<img src="img/tuisongtixing.png" class="navigation__icon">
<div class="navigation__text">打车</div>
</a>
<a href="#" class="navigation__item">
<img src="img/yuding_jiudianicon.png" class="navigation__icon">
<div class="navigation__text">订酒店</div>
</a>
</div>
</div>
</body>
</html>
代码分析
-
Block 定义:
.page
是页面的最外层容器,包含了整个页面内容。.search-bar
是搜索栏区域,负责搜索功能的展示。.navigation
是导航区域,包含多个导航选项。
-
Element 定义:
.page__header
是page
Block 的头部部分。.search-bar__icon
是search-bar
Block 中的图标元素,标识搜索按钮或其他功能。.search-bar__input
是search-bar
Block 中的输入框。.navigation__item
是navigation
Block 中的单个导航项。.navigation__icon
和.navigation__text
分别表示导航项中的图标和文本。
-
Modifier 应用:
- 在本示例中没有使用修饰符(Modifier),但可以想象当某个导航项被激活或处于不同状态时,可以通过
navigation__item_active
或navigation__icon_primary
等修饰符来控制样式。
- 在本示例中没有使用修饰符(Modifier),但可以想象当某个导航项被激活或处于不同状态时,可以通过
结语
通过 BEM 命名规范,可以显著提高代码的可读性、可维护性以及扩展性。在实际项目中,BEM 的规范不仅有助于团队协作,同时也减少了样式冲突,保证了项目的一致性。对于新手来说,尽量在取类名时考虑元素间的关联性,并遵循 BEM 规则,将为日后的开发与维护带来极大便利。