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__headpage__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__headerpage Block 的头部部分。
    • .search-bar__iconsearch-bar Block 中的图标元素,标识搜索按钮或其他功能。
    • .search-bar__inputsearch-bar Block 中的输入框。
    • .navigation__itemnavigation Block 中的单个导航项。
    • .navigation__icon.navigation__text 分别表示导航项中的图标和文本。
  3. Modifier 应用:

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

结语

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

相关推荐
庸俗今天不摸鱼12 分钟前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
黄毛火烧雪下19 分钟前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox29 分钟前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员
一张假钞32 分钟前
Firefox默认在新标签页打开收藏栏链接
前端·firefox
高达可以过山车不行32 分钟前
Firefox账号同步书签不一致(火狐浏览器书签同步不一致)
前端·firefox
m0_5937581033 分钟前
firefox 136.0.4版本离线安装MarkDown插件
前端·firefox
掘金一周37 分钟前
金石焕新程 >> 瓜分万元现金大奖征文活动即将回归 | 掘金一周 4.3
前端·人工智能·后端
三翼鸟数字化技术团队1 小时前
Vue自定义指令最佳实践教程
前端·vue.js
Jasmin Tin Wei1 小时前
蓝桥杯 web 学海无涯(axios、ecahrts)版本二
前端·蓝桥杯
圈圈编码2 小时前
Spring Task 定时任务
java·前端·spring