『精』CSS 小技巧之BEM规范

『精』CSS 小技巧之BEM规范.jpg

『精』CSS 小技巧之BEM规范

文章目录

  • 『精』CSS 小技巧之BEM规范
    • 一、什么是BEM?
    • 二、BEM要怎么用?
    • 三、不用BEM会少个胳膊吗?💊
    • 四、Sass与BEM的结合🎈
    • 五、块与修饰符应放在一块👿
    • 参考资料💘
    • 推荐博文🍗


一、什么是BEM?

BEM风格规范指的是 Block、Element、Modifier 这三者的简称,这个规范将 CSS 拆分成块、元素、修饰符,根本作用是帮助开发者快速理解HTML与 CSS 之间的关系。那么通过使用 BEM 能获得到什么好处呢?我罗列了下面几点:

  1. 如果我们想制作一个组件的新样式,比如改个字体/背景色,可以很容易地看到有哪些样式项已经存在,只需要新增一个修饰符即可,甚至可能意识到一开始就不需要编写任何样式,有一个预先存在的修饰符可以满足我们的需求。
  2. 得益于 CSS 命名语义化的好处,我们能够快速了解其 HTML 结构分布,一个元素依赖哪一个元素,在产品变更时快速更改其样式,并完全确信您的更改不会产生副作用
  3. 模块化的样式命名规则,能够最有效解决样式之间同名、继承、优先级等所带来的污染性问题,避免最后因为充斥着各种臃肿,而不敢触及修改遗留的各种未知样式,这其实给了开发人员一定的信心。
  4. 团队配合成本的降低,样式可读性的提高能够让成员之间能够快速复用已有的样式规则,而不需要再去编写一套样式。

在没有接触 BEM 之前,也许你会对我这罗列的这一堆优点一头雾水,这很正常让我们接着往下看,在看完本文的剩余内容时也许回过头你就能恍然大悟。
需要注意的是 BEM 并非是官方的风格规范,它是由Yandex团队开发,程序员之间约定俗成的一种契约规范,受众范围十分广泛,许多知名开源 UI 框架将其使用,如 Elementui、vant、uView-ui。但随着 tailwind 这类 CSS 框架的强势入局,BEM使用也有减少的趋势,毕竟只有在手动编写CSS代码的时候才用的上,如新起之秀,号称最完整Vue UI套件的 primevue。


二、BEM要怎么用?

要探究BEM怎么用,最简单的方法就是直接上手,让我们从编写一套有着丰富样式按钮组件开始,该组件包含最常见的颜色类型/大小切换功能。
可以看到属于 .btn 元素下的子项目,在命名时带上以父元素为头,__ 分割的命名,而按钮的不同状态颜色则通过基本样式名为头, -- 分割进行命名。以这样的命名方式,翻译过来就是基本样式名被称为块,__分割被称为元素,--分割则被称为修饰符。

<article class="btn-demo"><div class="btn btn--primary btn--large"><span class="btn__icon">$</span><span class="btn__text">按钮</span></div><div class="btn btn--info"><span class="btn__icon">$</span><span class="btn__text">按钮</span></div><div class="btn btn--mini"><span class="btn__icon">$</span><span class="btn__text">按钮</span></div><div class="btn btn--warn"><span class="btn__icon">$</span><span class="btn__text">按钮</span></div><div class="btn btn--danger"><span class="btn__icon">$</span><span class="btn__text">按钮</span></div>
</article>
@mixin mBtnType($m, $color,  $hoverColor, $activeColor, $fontColor: #FFF) {.btn--#{$m} {color: $fontColor;border-color: $color;background-color: $color;&:active, &:hover {color: $fontColor;}&:hover {border-color: $hoverColor;background-color: $hoverColor;}&:active {border-color: $activeColor;background-color: $activeColor;}}
}.btn-demo {display: grid;grid-template: 30px / repeat(4, 25%);grid-auto-rows: 30px;grid-row-gap: 20px;justify-content: space-between;justify-items: center;position: fixed;left: 50%;top: 20%;width: 450px;transform: translateX(-50%);
}.btn {$activeColor: #409EFF;box-sizing: border-box;display: flex;justify-content: space-between;align-items: center;width: 80px;height: 32px;padding: 5px 10px;border: 1px solid #F0F0F0;border-radius: 4px;color: #333;background-color: #FFF;cursor: pointer;&:active, &:hover {color: $activeColor;border-color: #A0CFFF;background-color: #ECF5FF;}&:active {border-color: $activeColor;}&__icon {font-weight: bold;}
}.btn--mini {width: 60px;height: 28px;font-size: .8em;
}.btn--large {width: 100px;height: 40px;font-size: 1.1em;
}@include mBtnType("primary", #409EFF, #79BBFF, #337ECC);
@include mBtnType("warn", #E6A23C, #EEBE77, #B88230);
@include mBtnType("danger", #F56C6C,  #F89898, #C45656);

示例中样式使用的是 Sass,如需查看 CSS 请安装 Sass 包将其转换成传统 CSS 代码。

# 安装Sass
npm i sass -g
# 将Sass编译成CSS
sass input.scss output.css

简单来说,BEM 最核心的写法就是用上 __-- 将样式命名进行区分。
2.1 按钮组件点击


三、不用BEM会少个胳膊吗?💊

这是个很冷笑话式的问题,在任何时间地点不使用BEM规范进行约束都不会让你少个胳膊少个腿,这些是约束自我的规则,其价值来自遵循它们,当然前提是你的项目规范支持你这么做,不然你的同事可能不介意帮你少个胳膊,哈哈😉
如果你不喜欢这么做,那大可不用纠结于此规范。
BEM模块化的规范必定会带来一些坏处,最明显的一个问题就是容易将名称命名过长,看起来臃肿而凌乱,这也是最常被用来反对 BEM 的论点,在我看来,这其实即使优点也是缺点,你也不希望这么一个选择器 p li .title {} 与你 HTML 结构命名一样的业务模块发生样式污染吧?
如果坚定了决心,那么在不使用BEM规范的情况下,还有什么比较好的CSS命名方法吗?以下面的示例演示,可以这么去做。

<article class="fruit-select"><div class="cell-list"><div class="cell-item"><span class="cell-text">香蕉</span><input type="checkbox" class="cell-checkbox"></div><div class="cell-item active"><span class="cell-text">榴莲</span><input type="checkbox" class="cell-checkbox"></div><div class="cell-item"><span class="cell-text">柚子</span><input type="checkbox" class="cell-checkbox"></div></div>
</article>

将HTML元素辅助的作用进行语义化,对CSS类名进行一个简单的命名,对于不同状态样式一块,考虑使用交集选择器进行编写。

.fruit-select {width: 200px;padding: 10px 0;border: 1px solid #666;
}.cell-list {display: flex;flex-direction: column;
}.cell-item {box-sizing: border-box;display: flex;justify-content: space-between;align-items: center;width: 100%;height: 40px;padding: 0 10px;
}.cell-item + .cell-item {border-top: 1px solid #666;
}.cell-item.active {color: #FFF;background-color: #FFA500FF;
}

当然这其实也是一个建议,至少在我没有接触到BEM规范之前的一段时间,我都是这么去书写我的代码。


四、Sass与BEM的结合🎈

BEM 毕竟只是应该风格规范,只要有需要手动编写样式的地方,就能发挥 BEM 的威力,将 Sass 与 BEM 搭配可大大提高开发效率,可谓是锦上添花。
在一开始的 二、BEM要怎么用? 示例代码中,就用到了 Sass,而 Sass 应用在前端框架中可以说是最常见的操作,接下来将完整的以 Vue + Sass 实现一个表格页面为例。

<script lang="ts" setup>/** 组件名: bem* 组件用途: bem规范示例页* 创建日期: 2023/12/27* 编写者: XianZhe*/import { reactive } from "vue";const $state = reactive({source: [["阿联酋迪拉姆", 193.89, 192.29, 195.25, 198.79, 193.42, "2023-12-27"],["澳大利亚元", 486.94, 486.44, 490.2, 491.62, 485.15, "2023-12-27"],["加拿大元", 539.83, 539.28, 543.45, 545.02, 538.58, "2023-12-27"],["瑞士法郎", 834.27, 833.6, 840.13, 842.47, 832.27, "2023-12-27"],["丹麦克朗", 105.47, 105.28, 106.31, 106.82, 105.11, "2023-12-27"],["欧元", 786.92, 780.98, 792.43, 794.48, 784.52, "2023-12-27"],["英镑", 905.71, 904.78, 911.78, 914.41, 904.36, "2023-12-27"],["港币", 91.34, 91.32, 91.68, 91.68, 90.9, "2023-12-27"],["印尼卢比", 0.0461, 0.0447, 0.0466, 0.0482, 0.0461, "2023-12-27"],["日元", 4.9913, 4.9912, 5.0247, 5.0267, 4.9951, "2023-12-27"],["美元", 713.21, 713.05, 716.05, 716.05, 710.02, "2023-12-27"]]});
</script><template><section id="bem" class="bem"><header class="bem__hd"><h2>BEM规范表格页</h2></header><main class="bem__bd"><table class="bem__table"><thead class="bem__table__hd"><tr><th>货币名称</th><th>现汇买入价</th><th>现钞买入价</th><th>现汇卖出价</th><th>现钞卖出价</th><th>中行折算价</th><th>发布日期</th><th>操作</th></tr></thead><tbody class="bem__table__bd"><tr v-for="(item, index) in $state.source" :key="index"><td v-for="sitem in item" :key="sitem">{{ sitem }}</td><td><div class="bem__table__operation"><span class="bem__table__operation-btn bem__table__operation-btn--danger">删除</span><span class="bem__table__operation-btn bem__table__operation-btn--primary">详情</span></div></td></tr></tbody></table></main><main class="bem__ft"><button class="bem__btn">你好</button></main></section>
</template><style lang="scss" scoped>.bem {&__bd {margin-bottom: 20px;}&__table {border-collapse: collapse;border: 1px solid #000;&__hd {background-color: #F0F0F0;}&__bd {tr {border-top: 1px solid #000;}}&__operation {display: flex;justify-content: space-between;align-items: center;padding: 0 10px;&-btn {cursor: pointer;}&-btn--primary {color: #409EFF;}&-btn--danger {color: #F56C6C;}}td {min-width: 100px;text-align: center;}}&__btn {width: 100px;height: 38px;border: unset;color: #FFF;border-radius: 4px;background-color: #409EFF;cursor: pointer;&:hover {background-color: #79BBFF;}&:active {background-color: #337ECC;}}}
</style>

4.1 BEM规范表格页
再来看看 ELement-ui 关于 BEM 应用的部分源码,以供更多参考,此源码取自 ELement-ui 级联组件部分。Element-ui 源码对于 BEM 的应用比较高级,简单来说就是利用 Sass 的 Mixin(混合),将 BEM 拆分成 b、e、m 三者的混合函数,再使用 include 注入到每一个组件之中。

@include b(cascader) {@include set-component-css-var('cascader', $cascader);display: inline-block;vertical-align: middle;position: relative;font-size: getCssVar('font-size', 'base');line-height: map.get($input-height, 'default');outline: none;&:not(.is-disabled):hover {.#{$namespace}-input__wrapper {cursor: pointer;box-shadow: 0 0 0 1px getCssVar('input', 'hover-border-color') inset;}}.#{$namespace}-input {display: flex;cursor: pointer;.#{$namespace}-input__inner {text-overflow: ellipsis;cursor: pointer;}.#{$namespace}-input__suffix-inner {.#{$namespace}-icon {height: calc(100% - 2px);svg {vertical-align: middle;}}}...}...
}

与之类似的还有Less这个CSS预处理器,使用起来和Sass是一样的道理。


五、块与修饰符应放在一块👿

看到下面这个选择器.cell__item--active,你会期待什么,正确的做法是将.cell__item--active.cell__item 放到一块,不能因为样式一样则直接使用,公共样式应该改用其他选择器样式。

<article class="cell__list"><div class="cell__item"><p class="cell__item--active">List item 1</p><button>按钮</button></div><div class="cell__item">...</div>
</article>

还有存在这种情况,不同的块覆盖同一层级的修饰符,不要这么做。

<style>.block__btn {color: #333;background-color: #FFF;border: unset;}.block__inner .block__btn--primary {background-color: #409EFF;}
</style>
<div class="block"><div class="block__inner"><button class="block__btn block__btn--primary">按钮</button></div>
</div>
  • 切勿覆盖不相关块中的修饰符。
  • 明确作用域原则,避免搞砸对 BEM 非常有帮助的特异性。

参考资料💘

🍅因发布平台差异导致阅读体验不同,源文贴出:《CSS 小技巧之BEM规范》

  • 网络文献:
    • getbem
    • css-tricks
    • why use bem?

推荐博文🍗

  • 『速查手册』HTML 语义化标签 | 语义化标签必要性?
  • 『干货』WebStorm代码模板配置大全

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

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

相关文章

100000000!文心一言披露最新用户规模

“文心一言用户规模突破1亿。” 12月28日&#xff0c;百度首席技术官、深度学习技术及应用国家工程研究中心主任王海峰在第十届WAVE SUMMIT深度学习开发者大会上宣布。会上&#xff0c;王海峰以《文心加飞桨&#xff0c;翩然赴星河》为题作了主旨演讲&#xff0c;分享了飞桨和文…

Page17~19 samp2_1, 项目各个文件的含义,增加一个关闭按钮

创建一个Widget Application项目samp2_1,选择QWidget作为窗体基类&#xff0c;并选中Generate form复选框 创建好之后&#xff0c;Shadow build的对勾去掉 创建好的项目文件目录树 这个项目包含以下一些文件&#xff1a; 项目组织文件samp2_1.pro, 存储项目设置的文件 主程序…

VStudio2022导出Qt项目在Linux的Qtcreator中运行修复错误记录

公司项目中的代码在VStudio2022中编写&#xff0c;交给我需要移植Linux的Qtcreator中&#xff0c;记录一下移植过程中的遇到的坑&#xff0c;按照错误顺序由高到低记录一下&#xff0c;边尝试边解决边记录&#xff0c;写作方面没有逻辑&#xff0c;每个人项目环境不一样&#x…

Flask 账号管理列表

Flask 账号管理列表 web/controllers/account/Account.py /index route_account Blueprint( account_page,__name__ )route_account.route( "/index" ) def index():resp_data {}req request.valuespage int( req[p] ) if ( p in req and req[p] ) else 1qu…

云服务器接入高防IP无法访问的原因以及处理方式

云服务器&#xff0c;也称为Elastic Compute Service&#xff08;ECS&#xff09;&#xff0c;是一种简单高效、安全可靠、处理能力可弹性伸缩的计算服务。它是一种虚拟化的服务器&#xff0c;运行公共的操作系统和软件&#xff0c;并允许用户通过网络进行访问。用户无需提前购…

PyTorch实战:基于Seq2seq模型处理机器翻译任务(模型预测)

文章目录 引言数据预处理加载字典对象en2id和zh2id文本分词 加载训练好的Seq2Seq模型模型预测完整代码结束语 引言 随着全球化的深入&#xff0c;翻译需求日益增长。传统的人工翻译方式虽然质量高&#xff0c;但效率低&#xff0c;成本高。机器翻译的出现&#xff0c;为解决这…

PYTHON基础:数据可视化绘图

python数据可视化入门 –常见的四种数据图形绘制 数据可视化在数据分析和数据科学中起着重要的作用。它可以帮助我们更直观地理解和解释数据&#xff0c;发现数据中的模式、趋势和异常。 在数据可视化中&#xff0c;常用的图表类型包括折线图、散点图、直方图和饼图&#xff…

为什么要运营海外社媒?海外云手机能发挥什么作用?

基于海外社媒在全球范围内拥有的大量流量&#xff0c;海外社媒运营成为了品牌推广、内容创作和用户互动的重要途径。本文将探讨海外社媒运营的重要性&#xff0c;并介绍海外云手机在这一过程中的卓越帮助。 海外社媒运营的重要性 首先&#xff0c;海外社媒运营有助于企业扩大品…

Qt高质量的开源项目合集

文章目录 1.Qt官网下载/文档2.第三方开源 1.Qt官网下载/文档 Qt Downloads Qt 清华大学开源软件镜像站 Qt 官方博客 2.第三方开源 记录了平常项目开发中用到的第三方库&#xff0c;以及一些值得参考的项目&#xff01; Qt AV 基于Qt和FFmpeg的跨平台高性能音视频播放框…

EasyExcel导出

1.简介 官网&#xff1a;EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 2.案例 2.1 实现的效果 效果图如下&#xff1a; 2.2 实现步骤 三种情景&#xff0c;主要是表头和数据有区别&#xff0c;简列实现步骤如下&#xff1a; 2.3 具体实现 2.3.1 前置-依赖导入…

【LeetCode-剑指offer】--3.比特位计数

3.比特位计数 class Solution {public int[] countBits(int n) {int[] bites new int[n 1];for(int i 0 ; i < n;i){bites[i] Count(i);}return bites;}public int Count(int x){int count 0;while(x > 0){x & (x - 1);count;}return count;} }

Python入门学习篇(十)——函数定义函数传参方式

1 相关定义和概念 1.1 函数的理解 一段被封装的可以重复调用的代码。 1.2 函数定义语法结构 def 函数名(形参1,形参2):要封装的逻辑代码 # 注意:函数可以有返回值也可以没有返回值,没有返回值的结果是None1.3 函数调用的语法结构 函数名(形参1,形参2)1.4 简单实例 1.4.1 …

同义词替换降低论文相似度的注意事项 papergpt

大家好&#xff0c;今天来聊聊同义词替换降低论文相似度的注意事项&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 标题&#xff1a;同义词替换降低论文相似度的注意事项 …

计算 10亿 的和,js 和 c 的处理时长对比

计算 10亿 的和&#xff0c;js 和 c 的处理时长对比 js 4.17s let sum 0; let start new Date().getTime(); for (let i0;i<1000000000; ii1){sum sum i; } let stop new Date().getTime(); console.log((stop - start)/1000, sum);结果&#xff1a; c 3.65s #in…

Windows搭建FTP服务器教学以及计算机端口介绍

目录 一. FTP服务器介绍 FTP服务器是什么意思&#xff1f; 二.Windows Service 2012 搭建FTP服务器 1.开启防火墙 2.创建组 ​编辑3.创建用户 4.用户绑定组 5.安装ftp服务器 ​编辑6.配置ftp服务器 7.配置ftp文件夹的权限 8.连接测试 三.计算机端口介绍 什么是网络…

解决ELement-UI懒加载三级联动数据不回显(天坑)

最老是遇到这类问题头有点大,最后也是解决了,为铁铁们总结了一下几点 一.查看数据类型是否一致 未选择下 选择下 二.处理数据时使用this.$set方法来动态地设置实例中的属性&#xff0c;以确保其响应式 三.绑定v-if 确保每次重新加载 四.绑定key 五.完整代码

进行VMware日志管理

随着公司转向虚拟化其 IT 空间&#xff0c;虚拟环境日志监控正在占据日志管理的很大一部分,除了确保网络安全外&#xff0c;虚拟机日志监控还有助于管理虚拟化工具&#xff0c;这是最复杂的任务之一。 对虚拟环境日志的监控分析 当今公司中最受欢迎的虚拟平台之一是 VMware。…

图像处理-周期噪声

周期噪声 对于具有周期性的噪声被称为周期噪声&#xff0c;其中周期噪声在频率域会出现关于中心对称的性质&#xff0c;如下图所示 带阻滤波器 为了消除周期性噪声&#xff0c;由此设计了几种常见的滤波器&#xff0c;其中 W W W表示带阻滤波器的带宽 理想带阻滤波器 H ( u …

二维码能转成链接吗?具体步骤是什么样的?

将二维码分解成链接来使用&#xff0c;是经常会出现的一种需求&#xff0c;分解成的链接可以放在电脑浏览器上&#xff0c;就可以在电脑上查看二维码的内容。那么如何将二维码图片做解码处理呢&#xff1f;最简单也是很多人会选择使用的一种方法就是使用二维码解码器来处理&…

如何提高代码质量:5 个基本步骤

软件开发团队有时会遇到各种挑战&#xff0c;导致他们难以按时生产高质量的项目。在这里&#xff0c;我们讨论了通过持续测试快速保证质量的五种策略。 每个人都想要更高质量、更快的软件。对现代软件开发团队的要求是巨大的——从日益激烈的竞争和市场压力、不断增加的功能和…