BEM 命名规范:高德地图实战

在前端开发中,命名规范的使用对项目的可维护性、可读性以及扩展性至关重要。本文将介绍 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

    1. page__head中有search-bar块
    2. search-bar块中有search-bar__input和search-bar__icon元素
  • page__body

    1. page__body中有navigation块
    2. navigation块中有navigation__item元素
    3. 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>

代码分析

  1. Block 定义:

    • .page 是页面的最外层容器,包含了整个页面内容。
    • .search-bar 是搜索栏区域,负责搜索功能的展示。
    • .navigation 是导航区域,包含多个导航选项。
  2. 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 分别表示导航项中的图标和文本。
  3. Modifier 应用:

    • 在本示例中没有使用修饰符(Modifier),但可以想象当某个导航项被激活或处于不同状态时,可以通过 navigation__item_active 或 navigation__icon_primary 等修饰符来控制样式。

结语

通过 BEM 命名规范,可以显著提高代码的可读性、可维护性以及扩展性。在实际项目中,BEM 的规范不仅有助于团队协作,同时也减少了样式冲突,保证了项目的一致性。对于新手来说,尽量在取类名时考虑元素间的关联性,并遵循 BEM 规则,将为日后的开发与维护带来极大便利。

相关推荐
PedroQue995 分钟前
0.8.2 新增 backFallback 配置,无 tabbar 页返回无忧
前端·uni-app
淡漠的蓝精灵13 分钟前
web.py:一个简单到极致的 Python Web 框架
开发语言·前端·python·其他
开开心心就好1 小时前
竖式除法出题工具,整除余数混合模式
运维·服务器·前端·javascript·ocr·perl·1024程序员节
起个名字费劲死了1 小时前
Halcon学习一:骰子识别
前端·python·学习
大江东去浪淘尽千古风流人物1 小时前
【HexVIO】DSP卸载双目惯性VIO:Hexagon向量化前端与单帧融合调度深度解析
前端·状态模式·slam·dsp·vio·hexagon·移动端加速
其实防守也摸鱼1 小时前
Chrome 扩展安全攻防实录:从攻击面到防御实践
开发语言·前端·网络·chrome·安全·web安全·php
web打印社区1 小时前
Lodop排障总纲-常见报错一张表
开发语言·前端·javascript·chrome·websocket
李剑一1 小时前
为什么几乎所有的知名开源项目都是外国人写的?
前端·ai编程·deepseek
小郎君6581 小时前
(一)为什么表单需要第三种状态:disabled、readonly 与纯文本展示
前端·vue.js
计算机魔术师1 小时前
1.4万亿没人接,OpenAI自己砍了1500亿
前端