BEM 命名规范与 CSS 重置:打造优雅的按钮页面实战

前端工程化从命名规范开始,本文将带你一步步实现一个符合 BEM 规范、具有良好视觉表现力的按钮页面,并深入解析背后的 CSS 设计思想。

前言

在日常开发中,你是否遇到过这样的问题:类名混乱、样式相互覆盖、维护困难?今天,我们将通过一个简单的按钮页面,学习 BEM 国际命名规范CSS Reset 的最佳实践,让你的样式代码更清晰、更易维护。

最终效果预览

我们实现了一个简洁的页面:顶部标题 + 描述区域,主体部分居中显示一组按钮(主要按钮、次要按钮),按钮之间有合适的间距,整体风格清爽,适配移动端。

一、HTML5 语义化标签 + BEM 结构

1.1 语义化 HTML5 结构

HTML5 提供了更语义化的标签,如 <header><main>,它们比纯 <div> 更能表达页面结构,对 SEO 和可访问性也更友好。

ini 复制代码
<div class="page">
    <header class="page_hd">
        <h1 class="page_title">这是一个页面</h1>
        <div class="page_desc">这是一个页面描述</div>
    </header>
    <main class="page_bd">
        <div class="button-sp-area">
            <a href="#" class="weui-btn weui-btn_primary">主要按钮</a>
            <a href="#" class="weui-btn weui-btn_default">次要按钮</a>
            <a href="#" class="weui-btn weui-btn_default">次要按钮</a>
        </div>
    </main>
</div>

1.2 BEM 命名规范详解

BEMBlock(块)、Element(元素)、Modifier(修饰符)的缩写,是一种前端命名方法论。

  • Block(块) :独立的组件或页面区块,如 .page.weui-btn
  • Element(元素) :块的组成部分,用双下划线 __ 连接(本文示例使用单下划线 _ 风格,这也是常见变体),如 .page_hd.page_bd
  • Modifier(修饰符) :表示块或元素的不同状态或样式变体,用双连字符 -- 连接(示例中使用 _ 连接修饰符),如 .weui-btn_primary

为什么使用 BEM?

优势 说明
结构清晰 从类名即可看出模块层级关系
命名唯一 有效避免样式冲突
可维护性高 团队协作时极易理解和复用
易读性强 .page_title 一目了然,无需猜测

在我们的代码中:

  • .page 是 Block,代表整个页面容器
  • .page_hd.page_bd.page_title 都是 Element,隶属于 .page
  • .weui-btn 是一个独立的按钮 Block
  • .weui-btn_primary.weui-btn_default 使用了 Modifier,表示不同样式的按钮

二、CSS Reset:告别浏览器默认样式差异

不同的浏览器对元素的默认样式(边距、字号、行高等)定义不同。为了拥有一致的基础样式,我们需要进行 CSS 重置。

2.1 为什么不直接用通配符 *

css 复制代码
/* ❌ 不推荐 */
* {
    margin: 0;
    padding: 0;
}

通配符会匹配所有元素,影响性能,并且无法处理一些特殊元素的默认样式(比如列表符号、表单边框等)。更好的做法是列出需要重置的常见元素。

2.2 专业的 Reset 片段

以下是我们使用的高质量 Reset,覆盖 HTML5 新元素、表单元素、媒体元素等:

css 复制代码
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
  box-sizing: border-box;  /* 统一盒模型,布局更可控 */
}

/* HTML5 块级元素兼容旧浏览器 */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
  display: block;
}

body {
  line-height: 1;
  min-height: 100vh;  /* 保证至少占满视口高度 */
}

ol, ul {
  list-style: none;
}

a {
  text-decoration: none;
  color: inherit;
}

img, picture, video {
  max-width: 100%;
  display: block;
}

几个关键重置点

  • box-sizing: border-box:让宽度包含 padding 和 border,避免子元素撑破父容器。
  • font: inherit:让表单元素继承父级字体,保持一致性。
  • min-height: 100vh:确保 body 至少占满视口,方便后续布局。

三、按钮组件设计:BEM 加持的 WeUI 风格

WeUI 是一套微信官方的 UI 库,它的按钮样式简约而经典。我们从中提取核心样式,并结合 BEM 实现。

3.1 基础按钮类 .weui-btn

css 复制代码
.weui-btn {
    position: relative;
    display: block;
    min-width: 184px;
    max-width: 280px;
    margin-left: auto;
    margin-right: auto;
    padding: 12px 24px;
    font-weight: 500;
    font-size: 17px;
    text-align: center;
    text-decoration: none;
    color: #fff;
    line-height: 1.41176471;
    border-radius: 8px;
    user-select: none;      /* 避免双击选中文本 */
}
  • margin-left/right: auto:水平居中(配合 display: block
  • min-width / max-width:保证按钮在不同屏幕下的合适宽度
  • 圆角 8px,现代风格

3.2 修饰符:不同按钮样式

css 复制代码
/* 主要按钮 - 微信绿 */
.weui-btn_primary {
    background-color: #07c160;
}

/* 次要按钮 - 半透明黑色背景 */
.weui-btn_default {
    color: rgba(0,0,0,0.9);
    background-color: rgba(0,0,0, 0.1);
}

3.3 相邻按钮间距处理

使用 相邻兄弟选择器 +,为除第一个以外的按钮添加上边距:

css 复制代码
.weui-btn + .weui-btn {
    margin-top: 15px;
}

这样既保证了间距,又避免了给容器添加多余的类。

四、页面布局细节

4.1 全屏页面容器

css 复制代码
.page {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
}

这里使用绝对定位使 .page 填满整个视口。也可以使用 height: 100vh 配合 margin:0,但绝对定位在复杂布局中更稳定。

4.2 头部区域

css 复制代码
.page_hd {
    padding: 40px;
}
.page_title {
    font-size: 20px;
    font-weight: 400;
}
.page_desc {
    margin-top: 4px;
    color: rgba(0,0,0,0.45);
    font-size: 14px;
}

注意 text-align: left 显式声明,防止某些全局居中样式影响。

4.3 按钮区域

css 复制代码
.button-sp-area {
    text-align: center;
    margin: 15px auto;
    padding: 15px;
}

外层容器负责居中,内部按钮通过自身的 margin: auto 实现块级居中。

五、完整代码整合

以下是完整的 HTML + CSS 代码(已合并展示),你可以直接复制到一个 .html 文件中运行。

xml 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>BEM规范 · 优雅按钮页面</title>
    <style>
        /* ========== CSS Reset ========== */
        html, body, div, span, applet, object, iframe,
        h1, h2, h3, h4, h5, h6, p, blockquote, pre,
        a, abbr, acronym, address, big, cite, code,
        del, dfn, em, img, ins, kbd, q, s, samp,
        small, strike, strong, sub, sup, tt, var,
        b, u, i, center,
        dl, dt, dd, ol, ul, li,
        fieldset, form, label, legend,
        table, caption, tbody, tfoot, thead, tr, th, td,
        article, aside, canvas, details, embed,
        figure, figcaption, footer, header, hgroup,
        menu, nav, output, ruby, section, summary,
        time, mark, audio, video {
            margin: 0;
            padding: 0;
            border: 0;
            font-size: 100%;
            font: inherit;
            vertical-align: baseline;
            box-sizing: border-box;
        }
        article, aside, details, figcaption, figure,
        footer, header, hgroup, menu, nav, section {
            display: block;
        }
        body {
            line-height: 1;
            min-height: 100vh;
            background-color: #ededed;
        }
        ol, ul { list-style: none; }
        a { text-decoration: none; color: inherit; }
        img, picture, video { max-width: 100%; display: block; }

        /* ========== 业务样式 ========== */
        .page {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
        }
        .page_hd {
            padding: 40px;
        }
        .page_title {
            font-size: 20px;
            font-weight: 400;
            text-align: left;
        }
        .page_desc {
            margin-top: 4px;
            color: rgba(0,0,0,0.45);
            font-size: 14px;
            text-align: left;
        }
        .button-sp-area {
            text-align: center;
            margin: 15px auto;
            padding: 15px;
        }
        .weui-btn {
            display: block;
            min-width: 184px;
            max-width: 280px;
            margin-left: auto;
            margin-right: auto;
            padding: 12px 24px;
            font-weight: 500;
            font-size: 17px;
            text-align: center;
            text-decoration: none;
            color: #fff;
            line-height: 1.41176471;
            border-radius: 8px;
            user-select: none;
        }
        .weui-btn_primary {
            background-color: #07c160;
        }
        .weui-btn_default {
            color: rgba(0,0,0,0.9);
            background-color: rgba(0,0,0, 0.1);
        }
        .weui-btn + .weui-btn {
            margin-top: 15px;
        }
    </style>
</head>
<body>
    <div class="page">
        <header class="page_hd">
            <h1 class="page_title">BEM 实战演示</h1>
            <div class="page_desc">符合 BEM 规范的页面与按钮组件</div>
        </header>
        <main class="page_bd">
            <div class="button-sp-area">
                <a href="#" class="weui-btn weui-btn_primary">主要按钮</a>
                <a href="#" class="weui-btn weui-btn_default">次要按钮</a>
                <a href="#" class="weui-btn weui-btn_default">另一个次要按钮</a>
            </div>
        </main>
    </div>
</body>
</html>

六、扩展思考与最佳实践

6.1 BEM 的常见变体

  • 双下划线元素.block__element
  • 双连字符修饰符.block__element--modifier
  • 本文使用单下划线是为了简洁,但推荐在大型项目中使用双下划线/双连字符,可读性更强。

6.2 何时使用 + 相邻选择器

相邻兄弟选择器非常适合处理列表项、按钮组等场景,它不依赖额外的类名,遵循"关注点分离"原则。但要注意,如果按钮数量动态变化,它依然完美工作。

6.3 CSS Reset 与 Normalize.css 的区别

  • Reset:抹平所有默认样式,完全由开发者定义。
  • Normalize:保留有用的默认样式,修复浏览器不一致问题。

本文使用的是轻量级 Reset,如果你更倾向于保留部分默认样式(如标题字号),Normalize.css 是更好的选择。

6.4 移动端优化要点

  • 设置 user-select: none 避免移动端长按弹出菜单。
  • 按钮最小尺寸 44×44pt(约 184px 宽度),符合手指点触舒适区。
  • 使用 border-radius: 8px 兼顾视觉与触感。

七、总结

通过这篇文章,我们不仅实现了一个干净漂亮的按钮页面,更重要的是学会了:

  1. BEM 命名规范:让 CSS 结构清晰、团队协作更高效。
  2. 语义化 HTML5:提升页面的可读性与 SEO。
  3. 专业的 CSS Reset:为项目提供一致的基础样式。
  4. 模块化按钮组件:可复用、易扩展。

命名规范是前端工程化的第一步,希望你能将 BEM 的思想融入到日常开发中,写出更优雅、更健壮的 CSS 代码。


如果觉得文章对你有帮助,欢迎点赞、收藏、关注。有任何疑问或想法,欢迎在评论区交流!

相关推荐
雨季mo浅忆1 小时前
记录利用Cursor快速实现首页数据大屏
前端·ai编程
像我这样帅的人丶你还1 小时前
🚀🚀🚀2026年还不会Nginx?
前端·nginx
用户059540174461 小时前
把对话记忆从内存搬到 Redis,长期记忆准确率从 63% 提升到 98%
前端·css
无心使然1 小时前
Openlayers图层按需分层渲染到不同Canvas画布
前端·vue.js·gis
木斯佳1 小时前
前端八股文面经大全:字节跳动-存储部门一面(2026-05-29)·面经深度解析
前端·状态模式
ayqy贾杰1 小时前
有AI了,我当超大头兵还苟得住吗?
前端·后端·架构
Aotman_1 小时前
JavaScript数组对象中指定字段转换
java·开发语言·前端·javascript·vue.js·前端框架·es6
姓蔡小朋友1 小时前
React基础
前端·react.js·前端框架