以大厂的方式带你重学CSS设计-BEM规范

256 阅读5分钟

BEM规范:让你的前端代码“整齐又好用”

介绍篇

做前端开发的朋友应该都有过这种体验:项目越做越大,代码越来越难管,样式也越来越乱。不同的开发者用不同的命名方式,导致代码看上去像“拼盘”,想改一个小地方,结果引发全局性大变动。这个时候,如果你能掌握BEM规范,就能轻松避免这些麻烦,代码也会变得更清晰、更好维护。

今天,我们来聊聊BEM是怎么让你的前端开发更轻松的,以及为什么它是前端开发界的“秘密武器”。 BEM代表的是Block(块)、Element(元素)和Modifier(修饰符)。它的核心思想是让每个模块的结构清晰可见,避免代码杂乱无章。每个组件都像一个独立的小模块,外部和内部的命名规则明确。

1. 块(Block)

**块(Block)**是一个独立的模块或者组件,是一个页面中具有特定功能的较大结构单元。它通常是一个可重用的组件,不依赖于其他元素或模块。块可以包含多个元素或子块,但它本身具有独立性,通常是页面中独立存在的部分。

  • 例子

    • header(头部)
    • menu(菜单)
    • button(按钮)
    • form(表单)
    • card(卡片)

特点

  • 块代表页面中的大结构单元,它通常是一个完整的功能模块。
  • 块是可以复用的,通常会出现在多个页面中。
  • 块具有自己的样式和行为,不依赖其他模块。

BEM命名规则

  • 块的名称使用单一的类名,例如:block-name
<div class="header">
  <h1 class="header__title">网站标题</h1>
</div>

在这个例子中,header 就是一个块(Block),它是页面的头部区域。


2. 元素(Element)

**元素(Element)**是块的一部分,它是块内的子组件,通常没有独立的功能,只有在其所在的块中才能发挥作用。元素不能单独存在,它们是为了实现块的功能而设计的。

  • 例子

    • 在 form 块中,input 字段、button 按钮、label 标签等都可以是元素。
    • 在 menu 块中,menu__item(菜单项)、menu__link(菜单链接)是元素。

特点

  • 元素是块的一部分,无法独立存在。
  • 元素是块的组成部分,通常为块提供更多的子功能。
  • 元素的命名总是包含其所属块的名称。

BEM命名规则

  • 元素的名称是块名和元素名的组合,使用双下划线(__)分隔,例如:block-name__element-name
<div class="header">
  <h1 class="header__title">网站标题</h1>
  <p class="header__subtitle">副标题</p>
</div>

在这个例子中,header__titleheader__subtitle 就是 header 块的元素(Element)。它们是 header 块的一部分,不能单独存在。

3. Modifier(修饰符)

Modifier表示Block或Element的状态或者变种,比如按钮的“主按钮”和“次按钮”。它的类名用--连接,比如weui-btn--primary表示主按钮。

.weui-btn--primary {
  /* 主按钮的样式 */
}

实战篇

接下来就让我们写一个微信的小页面来练练手吧! 腾讯的WEUI是一个基于BEM命名规范的前端框架,它通过模块化的设计和统一的命名规范,帮助开发者更高效地构建移动端的页面和应用。 我们打开他网站,用它里面的第一个button组件练练手。

image.png 我们打开开发者模式,选择手机端适配

image.png 我们可以看到页面长下面这个样子。

image.png 我们先观察以下页面,发现整体布局为上下结构。这时候我们就可以按照BEM命名规范,将整个页面命名为page,上半部分描述为page__hd,下半部分为page__bd。 而上半部分的元素中有一个大写的字体“button”,还有一个小写的中文字体,我们可以把他命名为page__title和page__desc。 下半部分是一组按钮,按钮区域是一个单独的部分,我们给它命名成一个块。按钮是一个通用的组件,所以我们把它按照Block的方式命名为一个块。弄清楚了结构,就可以使用emmet表达式快速生成结构。

<div class="page">
    <div class="page_hd">
        <h1 class="title">button</h1>
        <p class="desc">按钮</p>
    </div>
    <div class="page__bd">
        <button-area>
            <weui-btn>
                
            </weui-btn>
        </button-area>
    </div>
</div>

接着我们开始写他的样式。 我们可以把公通用的样式先写到一个样式表里,方便复用。建立common.css文件 首先我们先把元素的边框等元素重置。防止不同浏览器的设置不同造成的差异,详情可见之前的文章。 接着开始写通用属性

body, html{
  height:100%;
  //这行代码设置了HTML文档的`body`和`html`元素的高度为100%。这意味着整个页面的高度将填满浏览器窗口的高度
}

.page{
  position: absolute;//使用绝对定位,使容器相对于最近的定位祖先元素进行定位。
  
// 这些属性设置了容器的四个边缘与浏览器窗口的四个边缘对齐,从而使容器填满整个浏览器窗口。
 top: 0
  left: 0;
  right: 0;
  bottom: 0;

  background-color: rgb(245, 249, 245);
  overflow-y: auto;//如果容器的内容高度超过了容器的高度,这将允许容器在垂直方向上滚动。
}

接着创建button.css来定义button的属性

.page__hd{
  padding: 40px;
}
.page__title{
    text-align: left;
    font-size:20px;
    font-weight:400;
}
.page__desc{
    margin-top: 4px;
    color: rgb(0, 0, 0,0.5);
    font-size:14px;
    text-align: left;
}

.button-sp-area{
    margin: 15px auto;
    padding:15px;
    text-align: center;//设置内容物居中,也就是按钮居中
}

.weui-btn{
    display: block;//将按钮改成块级元素
    width: 184px;
    margin-left: auto;
    margin-right: auto;//设置居中
    padding:12px 24px;
    font-weight: 500;
    font-size: 17px;
    text-align: center;//设置按钮内的字居中
    line-height: 1.411;
    text-decoration: none;
    color: #fff;
    background-color: #07c160;
}

好了,这样按钮就设置成功了,不过大家可能会好奇,在.button-sp-area中不是已经通过text-align: center设置了内容物居中了吗?为什么在weui-btn还要通过margin来设置居中呢? 这是因为text-align: center只能设置行内元素或者行内块级元素,而按钮我们将他转换成了块级元素,因此要自己设置居中。