bem什么意思_BEM命名法

摘要

当你在编写css代码的时候,是否遇到这样的困扰: 不知道取什么class名? 修改某个组件的样式,担心影响了其他组件? 编写的组件样式如何复用?为了解决这些问题,聪明的程序猿发明了BEM命名法。

BEM命名法,是对css命名的一种规范,将页面模块化,隔离样式,提高代码的复用性,减少后期的维护成本。BEM的意思就是Block(块)、Element(元素)、modifier(修饰符),通过双下划线__或者双中划--链接。

BEM通常用于框架开发中,比如微信WEUI、饿了么element-ui、有赞vant等。笔者也是通过阅读这些优秀框架的源码,学习到了这一套css命名大法,从此走上人生巅峰,赢取白富美。

1. 为什么需要BEM命名法

样式隔离, 避免css样式污染

css样式污染的根本原因,是因为css没有作用域。BEM通过特殊的命名方式,给css创造一个“作用域”,就能有效避免css样式全局污染。例如,给输入框命名

# 普通
.base input {}# BEM命名法
.base-input__inner {}

普通的命名法, 会作用于所有class='base' 的后代元素。 本来你只想给当前元素加样式,结果不小心影响了其他元素,这就是样式污染。
BEM命名法,只会作用于class='base-input__inner'的元素, 达到样式隔离。 不会影响其他元素。
有人会说css-module, 也能实现css“作用域”,而且作用域更唯一,我为什么要用BEM ? 客官,别急,且听我慢慢道来。

代码更易覆盖

假如,客官你正在开发一个通用的输入框组件, 用了css-module。打包后是这个样子

.base-input-sdFh3sxLwo5uer {}

另一位客官,用了你的输入框组件,但是觉得样式不好看,想修改样式。试了半天,发现,根本无法用css精确选择你的组件,因为.base-input后面的hash值是动态的。于是,这位客官,捶胸顿足,发誓再也不用你的组件了。

代码更易读

还是刚刚的输入框组件,base-input__nner, 不需要我解释,客官一眼就能看出: base代表基础组件,input代表输入框组件, inner是组件中的某一块。
~哇~,客官你真是太聪明了!

2. 什么是BEM命名法

BEM其实是块(block)、元素(element)、修饰符(modifier)的缩写,利用不同的块,功能以及样式来给元素命名。这三个部分使用__--连接(这里用两个而不是一个是为了留下用于块的命名)。命名约定的模式如下:

.block{}
.block__element{}
.block--modifier{}
  • block代表更高级别的抽象或组件
  • block__element代表 block的后代,用于形成一个完整的block的整体
  • block--modifier代表block的不同状态或不同版本

常用规范

  1. block element modifier包含多个单词时, 用一个中划线-链接,例如
  2. el-dropdown-menu el-button
  3. blockelement用双下划线__链接, 例如
  4. 表单项 form__item
  5. 导航项 menu__item
  6. elementmodifier用双中划线--链接, 如表示按钮的不同状态,例如
  7. 默认:el-button--default
  8. 成功:el-button--success
  9. 用js控制样式时,css命名用is-开头,例如is-success、is-failed、is-disabled

常用的元素名

  • 表单元素 form form-item input select radio checkbox switch rate datePicker
  • 导航元素 nav subnav menu tab
  • 提示 alert message messageBox notification
  • 数据展示 table process tree pagiantion
  • 其他 button icon

3. 如何用好BEM命名法

页面命名

page-开头, page表示这是一个页面, 而不是组件。 给页面命名时,BEM可以搭配css-module一起使用。既能保证打包后选择器的唯一,又容易调试。例如

# 编译前
.page-index {}
.page-zufang {}# 编译后
.page-index-70yGFBg1eKjbSIwN {}
.page-zufang-mFTy62A1t83zjDbh {}

使用css-module, 打包后的clss名是可以修改的 参考

# 让打包后的文件更容易识别
{test: /.css$/,use: [{loader: 'css-loader',options: {modules: true,localIdentName: '[local]--[hash:base64:5]'}}]
}

页面中的选择器,都嵌套在页面根选择器内(.page-xxx), 保证所有样式, 只作用于当前页面。例如

<!- 页面命名 page-home ->
<div class="page-home"><div class="the-form"><div class="the-form-item"><div class="the-input"></div></div></div><div class="the-table"><div class="the-table-content"></div></div>
</div>.page-home {.the-form {}.the-form-item {}.the-input {}.the-table {}.the-table-content {}
}

公共组件命名

base-开头, base表示公共组件。

<div class="base-input"><input class="base-input__inner"/>   
</div># 选择器避免嵌套,降低选择器权重
.base-input {}
.base-input__inner {}

公共组件的每一个class名,带上组件的作用域前缀,如base-input__inner的作用域前缀是base-input

选择器不宜嵌套, 让选择器的权重尽可能低。原因如下: base-input__inner已经具有有作用域了,无需再嵌套。 由于组件选择器权重较低,在组件外修改组件样式时,覆盖样式非常方便。

局部组件命名

the-开头, the表示某一特定的组件。

<div class="the-header"><div class="the-header__title" /><div class="the-header__desc">
</div># 选择器避免嵌套,降低选择器权重
.the-header {}
.the-header__title {}
.the-header__desc {}

局部组件的每一个class名,带上组件的作用域前缀,如the-header__title的作用域前缀是the-header

局部组件,也不宜嵌套, 降低选择器权重。

局部组件也可以搭配css-module一起用,因为局部组件只给少数特定页面使用,修改样式,可以在组件内部直接修改。

4. 其他注意事项

命名语义化

怎样衡量你的命名是语义化的?让一个人新人,来看一下你的代码,不需要解释,就能知道这个类的作用,就比较语义化.

通常,可以根据模块的功能而命名,如页面头部header、导航栏nav、主体main、侧边栏sidebar、底部footer等,这样整个页面看起来就比较清晰了,维护起来也比较方便。

# bad
.fl { ... }
.fr { ... }# good 
# 左浮动
.is-float-left { ... }
# 右浮动
.is-float-right { ... }

上面的代码, fl、fr之类的命名,表达意思不够清晰,要知道具体的含义,还得去看代码。 而is-float-left, 就表达得非常清晰。

使用 class(类) 选择器, 避免使用 id、标签、伪类 选择器

标签、伪类 等选择器范围太广,不具有“作用域”的作用,会污染全局样式。例如,下面的代码中,.the-header a 选择器会选中the-header所有后代元素<a></a>

<div class="the-header"><a></a>
</div>
# bad
.the-header a { ... }

覆盖第三方组件样式时,重新起一个class名

使用原来的class名修改样式,可能会不小心影响了后代组件的样式。为了消除这个隐患,可以重新起一个class名,只作用于当前组件。例如修改ant-design的输入框组件样式

<div className="the-form"><Input className="the-input">
</div># bad 会影响the-form 后代的所有输入框
.the-form .ant-input {}# good 只会只用于className='the-input'的输入框
.the-form .the-input{}

总结

  • 为什么需要BEM命名法
  • 什么是BEM命名法
  • 如何用好BEM命名法
  • 其他注意事项

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/419878.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HDU1232——通畅工程(并查集)

http://acm.hdu.edu.cn/showproblem.php?pid1232 这道题是学习并查集的第一道题。 并查集&#xff0c;他的思路是构成一个树结构&#xff0c;如果这两个节点的根节点相同&#xff0c;那么说明这两个节点在一个集合里&#xff0c;否则不再一个集合。 查找根节点&#xff1a;当然…

小程序秒杀活动服务器,微信小程序官方上线张大仙周年活动,人数太多把服务器弄崩溃了...

原标题&#xff1a;微信小程序官方上线张大仙周年活动&#xff0c;人数太多把服务器弄崩溃了说起如今人气最旺的《王者荣耀》主播&#xff0c;莫过于就是靠着一手“素质直播”走遍天下的张大仙了。之前由于一些合同上面的问题&#xff0c;张大仙被迫停播了一段时间&#xff0c;…

curl 怎么在xp下使用_Http Post 快速使用

点击上方蓝字可直接关注&#xff01;方便下次阅读。如果对你有帮助&#xff0c;麻烦点个在看或点个赞&#xff0c;感谢~一直对http很陌生&#xff0c;这次借助libcurl分享一个快速使用http post的案例。平台&#xff1a;ubuntu16.04一、libcurl的安装1. Git上下载 master最新代…

2015-05-31

ARC4random 生成任意整数 要生成某一范围的数可以用取模运算 ID对象不能用点语法 Arc4random()%12 等价于arc4random_uniform(12) 文本框有个inputview 用来设置自定义键盘 toolbar 中的identifier 用来设置样式&#xff0c;其中flexible space为可伸缩的空条&#xff08;使右…

ajax 高并发请求,理解node.js处理高并发请求原理

很少分享技术文章&#xff0c;写的不好的地方请大家多多指教&#xff0c;本文是自己对于node.js的一些见解&#xff0c;如有纰漏请在评论区交流。高并发策略通常高并发的解决方案就是提供多线程模型&#xff0c;服务器为每个客户端请求分配一个线程&#xff0c;使用同步 I/O&am…

abaqus生成adams柔性体_基于ADAMS 的大型反铲挖泥机加装破碎锤 结构动力学分析

刘 斌 徐沪萍 王 磊武汉理工大学物流工程学院 武汉 430063摘 要&#xff1a;以配备液压破碎锤的反铲挖泥船反铲挖泥机为研究对象&#xff0c;简单介绍加装液压破碎锤方案&#xff0c;然后运用动力学理论和相关的动态仿真软件&#xff0c;通过建立反铲挖泥机的刚柔耦合模型&…

Vector 特性

1.Vector是一个连续内存占用的容器 2.每次Insert&#xff0c;都会将插入的对象先析构&#xff0c;然后复制一个副本添加到容器内 3.容器的大小先是1&#xff0c;然后是2&#xff0c;然后是4&#xff0c;也可以使用reserve来重新制定队列的长度 4.当erase删除一个或者clear之后&…

路由器桥接显示服务器已满,两个迅捷路由器经过有线桥接已经成功连接上,但是测试的时候副路由器却连接不上服务器?为什么?谢谢!...

主路由器工作模式为AP&#xff0c;第二级路由器设置WDS。简单点就是&#xff1a;主路由器就是普通上网设置&#xff0c;帐号密码&#xff0c;指定信道&#xff0c;无线密钥&#xff0c;DHCP启用等等&#xff0c;副路由器&#xff0c;只是设置信道&#xff0c;WDS打勾&#xff0…

rust加载不进去服务器eac_基于腾讯云的 Rust 和 WebAssembly 函数即服务

腾讯云云函数 (SCF) 已经支持十多种编程语言和运行时框架。腾讯云最近发布的 SCF custom runtime&#xff08;自定义运行时&#xff09;更进一步 —— SCF 现在可以支持用任何编程语言编写的函数。本文将介绍如何在云函数 SCF 中运行用 Rust 编写的 WebAssembly 函数。我们先介…

SChema中group指示器的使用

<?xml version"1.0" encoding"UTF-8"?> <!-- edited with XMLSpy v2011 (http://www.altova.com) by qmy (sigmartix) --> <xs:schema xmlns:xs"http://www.w3.org/2001/XMLSchema" elementFormDefault"qualified" a…

java ee项目部署到服务器上405,HTTP状态405 - HTTP POST方法不受此URL支持:采用的GlassFish服务器的NetBeans...

I am getting this error on using post method in my form-- HTTP Status 405 - HTTP method POST is not supported by this URL.我register.html文件如下&#xff1a;Register formName:Email ID:Password:我Register.java servlet代码是如下package Glassfish;import java.…

ceb怎么转换成word_PDF怎么转换成Word?分享免费转换技巧!

PDF怎么转换成Word&#xff1f;pdf格式无法编辑众所周知的事&#xff0c;但如果我们需要将其进行编辑使用的话&#xff0c;就需要将pdf格式转换成word格式。可是怎么将pdf转换成word一直是件令人头疼的事&#xff01;所以今天小编给大家分享几个pdf转word免费转换技巧&#xff…

[FZYZOJ 1038] 隧道

P1038 -- 隧道 时间限制&#xff1a;1000MS 内存限制&#xff1a;65536KB Description 一座小镇正在着手建造自己的地铁线路网。小镇坐落在许多小岛上&#xff0c;小岛之间通过隧道或者桥梁连接。地铁就在这些已有的桥梁和隧道的基础上建成。由于地铁主要是在地下&#xf…

音创ktv点歌系统服务器,音创ktv点歌系统家庭版

光行资源网为用户提供的音创ktv点歌系统电脑版是为ktv和家庭影院专门设计打造的点歌软件&#xff0c;相信很多朋友们都去过ktv点歌&#xff0c;大家点歌时的界面就是专门的点歌系统。特色1、方便性&#xff1a;安装调试简单方便&#xff0c;减少了您购买后所带来的多种维护烦恼…

7极限精简版64位_DNF:国服更新64位客户端深度体验,真的有如此丝滑吗?

DNF最新最快资讯&#xff0c;最全最细攻略&#xff0c;尽在骑乌龟的蜗牛12年&#xff0c;地下城的游戏客户端终于获得了升级&#xff0c;从32位更新到了64位&#xff0c;关于更新带来的游戏好处大家应该都在很多地方看过&#xff0c;而国服正式服也终于在8.20版本的更新中将客户…

MYSQL BENCHMARK函数的使用

MYSQL BENCHMARK函数是最重要的函数之一&#xff0c;下文对该函数的使用进行了详尽的分析&#xff0c;如果您对此感兴趣的话&#xff0c;不妨一看。 下文为您介绍的是MYSQL BENCHMARK函数的语法&#xff0c;及一些MYSQL BENCHMARK函数相关问题的测试&#xff0c;供您参考学习。…

服务器无法通过系统非页面共享区进行分配,服务器无法通过系统非页面共享区来进行分配的解决方法...

服务器开始阶段性的出现死机状态了。隔一段时间就无法连接了。重启后正常&#xff0c;过一段时间又是同样的问题。事件查看器中有大量的同样报错&#xff1a;事件ID&#xff1a;2020描述&#xff1a;服务器无法通过系统页面共享区来进行分配&#xff0c;因为共享区当前是空的。…