BEM命名及其在sass中的实践
Why use it
近几年web应用的发展可以用疯狂来形容,依靠浏览器的支持以及前端技术和框架的发展,很多应用已经把大量的逻辑从服务器端迁移到了浏览器端,使用前后端分离技术,浏览器端与用户进行交互来完成复杂的逻辑。由于这个发展趋势,Web应用的前端代码的复杂度大大提高,尤其是 JavaScript 和 CSS 代码的数量大幅增加,面对空前庞大的css和js代码量,形成科学的代码组织方法和命名规范迫在眉睫。
好的命名规则应该满足以下几个优点:
- 安全的命名,不会干扰其它css
- 我需要很快知道一个 class 位于这个伟大工程的什么位置
- class 尽可能少,且结构清晰
- 嵌套不可以太深,否则会形成难以维护的“谜”之样式
BEM
BEM 是一种前端项目开发的方法学,由 Yandex 公司提出。BEM 的名称来源于该方法学的三个组成部分的英文首字母,分别是块(Block)、元素(Element)和修饰符(Modifier)。这三个不同的组成部分称为 BEM 实体。
Block——块
块即是通常所说的 Web 应用开发中的组件或模块。每个块在逻辑上和功能上都是相互独立的。块中封装了组件相关的 JavaScript、CSS 代码和 HTML 模板。由于块是独立的,可以在应用开发中进行复用,从而降低代码重复并提高开发效率。块可以放置在页面上的任何位置,也可以互相嵌套。
Element——元素
元素是块中的组成部分。元素不能离开块来使用。BEM 不推荐在元素中嵌套其他元素。
Modifier——修饰符
修饰符用来定义块或元素的外观和行为。同样的块在应用不同的修饰符之后,会有不同的外观。
// 简单地说
.block { /* styles */ }
.block__element { /* styles */ }
.block--modifier { /* styles */ }
举个栗子
如何使用呢BEM命名方法呢?请先看以下例子:
//我们要为这个菜单写样式
<ul class="">
<li class="">Menu Item 1</li>
<li class="">Menu Item 2</li>
<li class="">Menu Item 3</li>
</ul>
1.“祖传”命名
放在以前,我们或许会这么写:
<ul class="nav">
<li class="item selected">Menu Item 1</li>
<li class="item">Menu Item 2</li>
<li class="item">Menu Item 3</li>
</ul>
看了一下,还是多清爽的。但是各位朋友是否注意到了一个问题:子元素item和其父元素menu,从命名上看,关系似乎太不紧密。一个box也可以有item子类,一个xxx也可以包含一个item子类。看看其样式的写法:
//sass
.nav {
list-style: none;
.item {
font-weight: bold;
&.selected {
color: red;
}
}
}
//编译后产生的css
.nav {
list-style: none;
}
.nav .item {
font-weight: bold;
}
.nav .item.selected {
color: red;
}
从样式文件上看,仿佛也没有太大问题,但是,这是在我们代码层数较少的情况。如果是一个复杂的页面元素,我们sass层级会非常深。编译后的css,层级也会很深。
2.BEM命名
现在我们使用BEM再来编写看看:
<ul class="nav">
<li class="nav__item nav__item--selected">Menu Item 1</li>
<li class="nav__item">Menu Item 2</li>
<li class="nav__item">Menu Item 3</li>
</ul>
//sass
.nav {
list-style: none;
&__item {
font-weight: bold;
&--selected {
color: red;
}
}
}
//使用sass编译后的css是
.nav {//菜单
list-style: none;
}
.nav__item {//菜单item
font-weight: bold;
}
.nav__item--selected { //被选中的菜单item
color: red;
}
乍看之下,根据 BEM 命名规则产生的 CSS 类名都会很复杂,但实际上在熟悉了命名规则之后,可以很容易理解其含义。其次,css不再存在复杂的层级关系,浏览器渲染的时候,样式系统从最右边的选择符开始向左进行匹配规则。只要当前选择符的左边还有其他选择符,样式系统就会继续向左移动,直到找到和规则匹配的元素,或者因为不匹配而退出,减少层级就能提升性能,对应静态css文件大小也会减少。
很多人会吐槽两个下划线和两个横杠作为连接符,并不优雅。但是我觉得,BEM是一种思想,是我们需要理解的,至于我们用什么样的连接符,什么样的方式实现,可以根据自己项目的情况考虑。
BEM命名及其在sass中的实践的更多相关文章
- CSS BEM 命名规范简介
[前言] BEM 是一个简单又非常有用的命名约定.让你的前端代码更容易阅读和理解,更容易协作,更容易控制,更加健壮和明确,而且更加严密.这篇文章主要介绍了CSS BEM 命名规范简介(推荐)的相关资料 ...
- 更好用的css命名方式——BEM命名
一.什么是BEM? BEM代表块(Block),元素(Element),修饰符(Modifier).无论是什么网站页面,都可以拆解成这三部分. 二.带你认识网页 我们来看一下qq的官网,它可以由三个块 ...
- TypeScript在react项目中的实践
前段时间有写过一个TypeScript在node项目中的实践. 在里边有解释了为什么要使用TS,以及在Node中的一个项目结构是怎样的. 但是那仅仅是一个纯接口项目,碰巧赶上近期的另一个项目重构也由我 ...
- 一篇关于BEM命名规范
一直以来自己对命名都是比较混乱的,并没有一个比较好的格式来命名,最近自己碰巧学习到了BEM命名规范,我想谈谈自己的理解以供自己来学习,同时也可以和各位大佬一起学习. BEM是一个很有用的方法可以创建复 ...
- CSS — BEM 命名规范
推荐阅读: https://juejin.im/post/5b925e616fb9a05cdd2ce70d 1 什么是 BEM 命名规范 Bem 是块(block).元素(element).修饰符(m ...
- Android架构(一)MVP架构在Android中的实践
Android架构(一)MVP架构在Android中的实践 https://www.300168.com/yidong/show-2790.html 核心提示:为什么要重视程序的架构设计 对程序进 ...
- Sass中连体符(&)的运用
在CSS中,这种想法是无法实现的,但在Sass中,可以轻松的通过连体符&来实现.这也是我们今天要说的. 我们先来回忆一下,CSS中常见的一组样式: /*页面中链接的颜色*/ a {clolor ...
- Mysql事务探索及其在Django中的实践(二)
继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...
- WPF:指定的命名连接在配置中找不到、非计划用于 EntityClient 提供程序或者无效的解决方法
文/嶽永鹏 WPF 数据绑定中绑定到ENTITY,如果把数据文件做成一个类库,在UI文件中去应用它,可能遇到下面这种情况. 指定的命名连接在配置中找不到.非计划用于 EntityClient 提供程序 ...
随机推荐
- ARM7探究
1.流水线:三级流水线 预取.译码.执行.三级并行发生 2.什么是哈佛结构? 哈佛结构是一种存储器结构,是一种并行体系结构,它的主要特点是将程序和数据存储在不同的存储空间中,即程序存储器和数据存储器是 ...
- deeplearning.ai 人工智能行业大师访谈
Geoffrey Hinton 1. 怀揣着对大脑如何存储记忆的好奇,Hinton本科最开始学习生物学和物理学,然后放弃,转而学习哲学:然后觉得哲学也不靠谱,转而学习心理学:然后觉得心理学在解释大脑运 ...
- Coupled model
常见的coupled models phase English paper WRF-Chem mechanism public data 一些重要的结论 干空气的状态方程 ECWMF驱动WRF 常见的 ...
- 使用jxl操作之一: 实现对Excel简单读写操作
项目目录树 对象类UserObject UserObject.java package com.dlab.jxl; public class UserObject { private String u ...
- XP停止更新不用愁 瑞星XP护盾给你持续保护
4月8日,微软正式结束了Windows XP的支持,所有XP系统将不会再收到来自微软提供的补丁和安全更新等服务,叱咤OS江湖十几年的一代操作系统终于完美谢幕.但谢幕不等于消失,据相关机构统计,虽然微软 ...
- Markdown 内嵌 HTML 语法
Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式.Markdown内嵌HTML,本文总结了一些常用的HTML标记用于扩展Markdow ...
- Synchronized的jvm实现
参考文档: https://www.cnblogs.com/dennyzhangdd/p/6734638.html
- python jQuery筛选器
筛选器:$(this).next() 下一个 $(this).prev 上一个 $(this).parent() 父 $(this).children() 孩 $(th ...
- docker 使用:创建nginx容器
在上一节中了解了镜像和容器.对于镜像可以这样的理解,镜像相当于一个光盘,里面刻录了一个系统这个系统已经带有相关的服务了. 容器是通过镜像这个光盘安装的一个操作系统,光盘预加了什么服务,容器就有什么服务 ...
- centos7限制普通用户访问单一目录下的单一文件
要求给开发同事开设一个查看日志的账号,并限制其只能访问该目录下的单一文件 1.先新建账号 useradd loglook passwd loglook 家目录为/home/loglook 2.日志的属 ...