前言:
在面试中,关于BEM命名法的问题很常见,尤其是对于前端开发岗位。面试官可能会通过多种方式来评估我们对BEM的理解和实际应用能力。如:
问题: 你能解释一下什么是BEM命名法吗?它解决了前端开发中的哪些问题?
问题: 给定一个页面组件(如导航栏),请用BEM命名法来设计其CSS类名结构。
问题: 在一个复杂的组件中,如何使用BEM有效地管理嵌套层级和避免类名过长的问题?
......等等等等,接下来在这里我们讲解BEM命名规范和实现一个大厂前端案例。
BEM命名
BEM(Block Element Modifier)是一种国际上广泛应用的前端开发命名方法论,主要用于提高CSS的可维护性和可重用性。这一方法由Yandex团队提出,旨在通过明确的命名规则来组织和管理HTML和CSS中的组件。BEM命名法的核心理念是将用户界面拆分成基本的逻辑单元,并清晰地定义它们之间的关系。
Block(块):
表示一个独立的、可复用的组件或一个页面区域,具有明确的功能和语义。例如,header、menu 或 form 都可以是一个块。
Element(元素):
是块的一部分,没有独立的意义,只能在特定块的上下文中使用。元素的名称总是与它的块相关联,通过双下划线__连接。例如,header__logo 或 menu__item。
Modifier(修饰符):
用于描述块或元素的不同状态、版本或附加特性。修饰符通过双中划线--与块或元素的名称相连。修饰符可以改变块或元素的外观或行为,如 button--primary 或 list__item--active。
BEM命名法的优势在于它强制执行了一种结构化的、自我解释的命名模式,这有助于开发者理解代码结构,减少样式间的意外冲突,并使得代码易于维护和团队协作。由于其强调模块化和可维护性,BEM成为了许多大型项目和框架的首选命名约定。
实现抖音主页页面 信息栏和功能栏
抖音主页功能选项页面在ipad中打开时是可以将全部展开的,而在手机移动端是不能全部展开,但是能左右滑动查看。
这里我们将用一段代码,还原出在两个不同客户端的界面效果,同时使用BEM命名规范代码书写,进行创建更贴近大厂实际开发的项目。
这里我们先分析页面结构。
页面主体分为两个大模块info和tab,然后info中又有个人签名signature和地区和添加个人其他信息模块home;tab栏中有单个项目item,item上半部分是ico图标,下半部分是title文字说明。有了这些信息的提取我们的结构就出来了
*<!-- 个人块-信息元素 -->*
<div class="dy-person-info">
*<!-- 个性签名 -->*
<div class="dy-person-info_signature">祝你开心</div>
*<!-- 地址 -->*
<div class="dy-person-info_home">中国澳门</div>
<div class="dy-person-info_home">+年龄学校等标签</div>
</div>
*<!-- 栏目块 -->*
<div class="dy-tab">
*<!-- 栏目块-单个项目 -->*
<div class="dy-tab-item">
*<!-- 图标 -->*
<div class="dy-tab-item_icon iconfont icon-gouwuche"></div>
*<!-- 标题 -->*
<div class="dy-tab-item_title">抖音商城</div>
</div>
</div>
将结构设计倾斜命名规范后我们开始着手CSS排版:
* {
margin: 0;
padding: 0;
outline: 0; */*轮廓 不同的浏览器不一样*/*
box-sizing: border-box;
}
.dy-person-info{
width: 100%;
}
.dy-person-info_signature{
margin: 20px;
font-size: 20px;
}
.dy-person-info_home{
display: inline;
margin-left: 20px;
font-size: 20px;
background-color: rgb(152, 151, 151);
-webkit-user-select: none;
user-select: none;
}
.dy-tab{
display: flex;
margin-top: 20px;
overflow-x: scroll;
padding-right: calc(17px + env(safe-area-inset-right));
}
*/* 隐藏滚动条 */*
.dy-tab::-webkit-scrollbar {
width: 0; */* 设置宽度为0隐藏水平滚动条 */*
height: 0; */* 如果需要隐藏垂直滚动条,设置高度为0 */*
}
.dy-tab-item{
width: 100px;
text-align: center;
-webkit-user-select: none;
user-select: none;
}
.dy-tab-item + .dy-tab-item{
margin-left: 20px;
}
.dy-tab-item_icon{
font-size: 40px;
font-weight: 400;
}
.dy-tab-item_title{
width: 120px;
font-size: 20px;
font-weight: 400;
}
这里的CSS样式我们不细讲,但是这里要提出两个重要的样式:
padding-right: calc(17px + env(safe-area-inset-right));
-webkit-user-select: none;
user-select: none;
有没有大佬知道这是什么操作。
其实一般的项目而言,着几个属性加不加上并不会影响项目,但是对于抖音这种超级软件,它的用户体验感一定是要被优化到极致的。
padding-right: calc(17px + env(safe-area-inset-right))
这是为苹果用户专门添加的 ,是为了处理移动设备上(尤其是iPhone和iPad等苹果设备)由于屏幕边缘的圆角设计和顶部的刘海(或底部的Home Indicator)导致的可触控区域减少的问题。这是所谓的“安全区域”概念。
-webkit-user-select: none; user-select: none;
是为防止长按时会弹出复制文字的效果,例如当你手湿湿的时候去触碰手机,或者是水滴在手机上,形成的误触,弹出的复制文字效果是非常降低用户的体验感的。就像这一样的
如果使用-webkit-user-select: none和user-select: none;之后便不会再出现这个效果了。
那为什么有两个样式属性呢,这也是大厂级项目的精细之处:
user-select: none;是chrome推出的实验属性一般只能在近些年的手机上起作用。 而-webkit-user-select: none;是已经早就被推广的属性,对于很久以前的手机也是适用的。 所以有没有感受到来自大厂为提高用户体验的细致。
最后把代码全贴:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./download/font_4563834_ah9gfiyordj/iconfont.css">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
outline: 0; */*轮廓 不同的浏览器不一样*/*
box-sizing: border-box;
}
.dy-person-info{
width: 100%;
}
.dy-person-info_signature{
margin: 20px;
font-size: 20px;
}
.dy-person-info_home{
display: inline;
margin-left: 20px;
font-size: 20px;
background-color: rgb(152, 151, 151);
-webkit-user-select: none;
user-select: none; */*防止长按弹出复制等等select*/*
}
.dy-tab{
display: flex;
margin-top: 20px;
overflow-x: scroll;
*/* 考虑到iOS边框安全区域 */*
padding-right: calc(17px + env(safe-area-inset-right));
}
*/* 隐藏滚动条 */*
.dy-tab::-webkit-scrollbar {
width: 0; */* 设置宽度为0隐藏水平滚动条 */*
height: 0; */* 如果需要隐藏垂直滚动条,设置高度为0 */*
}
.dy-tab-item{
width: 100px;
text-align: center;
-webkit-user-select: none;
user-select: none; */*防止长按弹出复制等等select*/*
}
.dy-tab-item + .dy-tab-item{
margin-left: 20px;
}
.dy-tab-item_icon{
font-size: 40px;
font-weight: 400;
}
.dy-tab-item_title{
width: 120px;
font-size: 20px;
font-weight: 400;
}
</style>
</head>
<body>
*<!-- 个人块-信息元素 -->*
<div class="dy-person-info">
*<!-- 个性签名 -->*
<div class="dy-person-info_signature">祝你开心</div>
*<!-- 地址,+标签 -->*
<div class="dy-person-info_home">中国澳门</div>
<div class="dy-person-info_home">+年龄学校等标签</div>
</div>
*<!-- 栏目块 -->*
<div class="dy-tab">
*<!-- 栏目块-单个项目 -->*
<div class="dy-tab-item">
*<!-- 图标 -->*
<div class="dy-tab-item_icon iconfont icon-gouwuche"></div>
*<!-- 标题 -->*
<div class="dy-tab-item_title">抖音商城</div>
</div>
<div class="dy-tab-item">
<div class="dy-tab-item_icon iconfont icon-shizhong"></div>
<div class="dy-tab-item_title">观看历史</div>
</div>
<div class="dy-tab-item">
<div class="dy-tab-item_icon iconfont icon-shu"></div>
<div class="dy-tab-item_title">我的读书</div>
</div>
<div class="dy-tab-item">
<div class="dy-tab-item_icon iconfont icon-qianbao"></div>
<div class="dy-tab-item_title">我的钱包</div>
</div>
<div class="dy-tab-item">
<div class="dy-tab-item_icon iconfont icon-lianxiren"></div>
<div class="dy-tab-item_title">经常访问的人</div>
</div>
<div class="dy-tab-item">
<div class="dy-tab-item_icon iconfont icon-yinle"></div>
<div class="dy-tab-item_title">我的音乐</div>
</div>
<div class="dy-tab-item">
<div class="dy-tab-item_icon iconfont icon-gengduo"></div>
<div class="dy-tab-item_title">查看更多</div>
</div>
</div>
</body>
</html>
效果图:
这里移动端模式下是可以滑动的,图片演示不出来,大家可以跑一下去试试
总结
顶级大厂做出来的产品,用户体验感是非常看重的,不论多小的细节一定都会做到极致。而对于内部代码的书写也是有着一套命名书写规范,在提高团队合作效率的同时也提升了代码的可读性和可维护性。