BEM-CSS实战抖音团购模块
BEM的介绍
BEM是一种前端开发中用于CSS类名命名的方法论。通过提供一种标准化的命名方式来解决CSS类名的可读性和可维护性问题。BEM三个字母拆分开来可视为独立的块(Block)、元素(Element)和修改器(Modifier)
BEM的组成部分:
-
块(Block):代表页面上的独立组件或模块,如按钮、导航栏、表单等。块是自包含的,并且可以在整个项目中重复使用。
-
元素(Element):块内的子组件,它们是块的一部分,但通常不独立存在。元素的命名需要在块的类名前加上两个下划线
__
,如.page__hd
。 -
修改器(Modifier):用于表示块或元素的不同状态或变体。修改器的命名需要在块或元素的类名后加上两个连字符
--
,如.page--large
或.page--centered
。
使用示例:
假设我们有一个按钮组件,它有一个文本元素和一个悬停状态的修改器:
<div class="dy-page">
<div class="dy-page__hd">
<a href="#" class="dy-page__item">
<span class="dy__title">南昌</span>
</a>
在这个示例中:
.dy-page
是块。.dy-page__hd
可以是块中的头部组成成分。.dy-page__item
是按钮的修改器。
BEM方法论因其清晰和一致的国际命名规则而广受前端开发者的欢迎,非常有助于创建可维护和可扩展的前端代码。
BEM的优点:
- 便利性: 新手在写页面时,结构一般不太会有问题,取类名时候浪费时间。
- 可读性: 通过明确的命名规则,开发者可以很容易地理解类名的含义和它们之间的关系。
- 可维护性: 标准化的命名使得代码更加一致,便于团队协作和后期维护。
- 避免样式冲突: 由于每个块和元素都有独特的类名,因此减少了样式冲突的可能性。
开始实战——抖音团购
话不多说,开始在实战中应用到BEM方法论来构建结构
首先我们来分析一下:
- 这整个功能模块是淘宝页面的一小个功能部分,所以我们可以把这整个功能模块看作一个块(block),我们给他起名叫:
dy-page
- 在这整个块里分上下两个部分(element),上部分我们起名为:
dy-page__hd
;下部分叫:dy-page__bd
- 在上面的部分中,分为两个左右小部分,我们给他起名为:
tb-order__item
和dy-page__search
,而在dy-page__search
中又含有两个左右小部分为搜索框dy-page__search-input
,dy-page__search_on
- 在下面的部分中,分为左右排列的四个小部分,也为:
tb-order__item
;这每个小部分中都有一个小圆点的元素,代表着当前各个页面情况的一个数量,我们在这给他起名为:dy__pointer
;当它有数量的时候才进行显示,给他添加上状态(modefier):dy__pointer_on
第一部分
将dy-page
整体分割为两大部分dy-page__hd
和dy-page__bd
第二部分
将头部先细分为两部分tb-order__item
和dy-page__search
再将dy-page__search
细分为两部分dy-page__search-input
和dy-page__search_on
第三部分
将身体部分细分为四个tb-order__item
组成
再将tb-order__item
右上角增添一个角标
附上完整HTML代码
<body>
<div class="dy-page">
<div class="dy-page__hd">
<a href="#" class="dy-page__item">
<span class="dy__title">南昌</span>
</a>
<div class="dy-page__search">
<input type="search" placeholder="........." name="query" class="dy-page__search-input">
<div class="dy-page__search_on">搜索</div>
</div>
</div>
<div class="dy-page__bd">
<a href="#" class="dy-page__item">
<img src="image/待办项.png" >
<span class="dy__pointer"></span>
<p class="dy__desc">团购订单</p>
</a>
<a href="#" class="dy-page__item">
<img src="image/收藏.png" >
<span class="dy__pointer"></span>
<p class="dy__desc">团购收藏</p>
</a>
<a href="#" class="dy-page__item">
<img src="image/优惠卷.png" >
<span class="dy__pointer dy__pointer_on">4</span>
<p class="dy__desc">优惠卷</p>
</a>
<a href="#" class="dy-page__item">
<img src="image/评价中心.png" >
<span class="dy__pointer dy__pointer_on">8</span>
<p class="dy__desc">评价中心</p>
</a>
</div>
</div>
</body>
接着编写CSS样式:
提出几个小点可以让你的页面更加丝滑更富有高级感
-
重置样式 默认样式重置,对所有浏览器都公平,防止辛苦制作的页面在有些页面加载错误
-
-webkit-tap-highlight-color: transparent;
让按钮摁上去的高亮颜色为透明(transparent) -
font-family: system-ui, -apple-system, sans-serif;
调整字体 ,适用用户系统,为苹果用户优化 支持苹果特殊字体 -
overflow-y: auto;
设置为滚动条 page正好为一屏高度,但内容超出屏幕就可以使用滚动条 -
-webkit-overflow-scrolling: touch;
滚动条优化,如德芙般丝滑,让屏幕感受到你的触碰 -
display: flex;
启用Flexbox布局justify-content: flex-end;
在Flexbox布局使子元素靠右排列 -
搜索框的详细设置(让搜索边框消失,且点击时依然为透明状态)
.dy-page__search{
width: 80%;
height: 40px;
border-radius: 10px;
border: 2px solid #fe0000;
margin: 10px;
display: flex; /* 启用Flexbox布局 */
justify-content: flex-end; /* 子元素靠右 */
}
- 使头部和身子部分分隔开,让页面看起来更加高级
css高级选择器 兄弟选择器
block + block
中间的加号代表着下面的块与上面的块之间的距离
.dy-page__hd+.dy-page__bd{
margin-top: 16px;
}
附上完整CSS代码(含注释)
<style>
/* 重置样式 默认样式重置,对所有浏览器都公平 (IE干了很多坏事)*/
*{
margin:0;
padding:0;
/*outline: 0;轮廓属性,不同的浏览器不一样*/
}
/* css inherit 继承,所有子元素会继承*/
body,html{
height: 100%;
/* 摁上去的高亮颜色 transparent透明*/
-webkit-tap-highlight-color: transparent;
}
a{
text-decoration: none;/* 取消下划线*/
}
body{
/* 字体 ,看用户系统,为苹果用户优化 支持苹果特殊字体*/
font-family: system-ui, -apple-system, sans-serif;
background-color: #bbb6b6;
letter-spacing: 1px;
}
.dy-page{
position: absolute;
top: 10px;
left: 4px;
bottom:0;
right: 4px;
overflow-y: auto;/* 滚动条 page正好为一屏高度,但内容超出屏幕就可以使用滚动条*/
-webkit-overflow-scrolling: touch;/* 滚动条优化,如德芙般丝滑,让屏幕感受到你的触碰*/
}
.dy-page__hd{
height:63px;
padding:0 2px;
display: flex;
justify-content: space-between;/*两端对齐*/
align-items: center;
border-radius: 20px;
background-color: white;
}
.dy__title{
font-size: 20px;
font-weight:bold;
/* line-height:63px; */
}
.dy-page__search{
width: 80%;
height: 40px;
border-radius: 10px;
border: 2px solid #fe0000;
margin: 10px;
display: flex; /* 启用Flexbox布局 */
justify-content: flex-end; /* 子元素靠右 */
}
.dy-page__search-input {
width: 80%;
padding: 10px;
box-sizing: border-box; /* 包括边框和内填充在总宽度内 */
border: 1px solid transparent;/* 边框透明 */
border-radius: 10px;
outline: none; /* 移除选中时默认边框 */
}
.dy-page__search_on{
width:20%;
height: 30px;
color:rgb(255, 255, 255);
font-size: 16px;
background-color: #fe0000;
border-radius: 10px;
text-align: center;
line-height: 30px;
margin: 5px;
}
.dy-page__bd{
height:60px;
display: flex;
justify-content: space-around;
border-radius: 20px;
background-color: white;
padding: 10px;
}
.dy-page__item{
width:20%;
text-align: center;
color:black;
position: relative;
}
.dy__desc{
font-size: 14px;
}
.dy__pointer{
width:22px;
height:22px;
position: absolute;
display: inline-block;
color:white;
top:-9px;
right:18px;
border-radius: 50%;
line-height: 22px;
font-size:11px;
font-weight: 550;
}
.dy__pointer_on{
background-color: #ff4102;
}
/*css高级选择器 兄弟选择器*/
.dy-page__hd+.dy-page__bd{
margin-top: 16px;
}
img{
width: 30px;
height: 30px;
}
</style>
最后抖音团购模块的一部分就算做完了,可以参照一下抖音的页面,我制作的并不完美
总结
在我学习BEM之前写文章总会遇到许多奇奇怪怪的问题,命名时比较随意,缺乏了一致性,导致在后来重新看我的代码时难以理解和维护,在大型项目中类名不够具体,可能会遇到样式覆盖的问题,缺乏清晰的结构和命名规则
为了避免这些问题于是认真研究了BEM方法论,让代码的条理性更好方便自己或者其他开发者阅读,还能减少样式的冲突,也为后续的维护工作提供了极大的便利
转载自:https://juejin.cn/post/7373946076761866277