-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
如何理解前端BEM? #46
Comments
BEM概览BEM - Block Element Modfier(块元素编辑器)是一个很有用的方法,它可以帮助你创建出可以复用的前端组件和前端代码 它有如下3个特性:
下面将从3个方面来分析BEM到底是什么? BEM介绍BEM是一个高可用的,强大的,而且简单的命名规范,它可以使得你的前端代码更加易读和理解,容易与他人协作,容易扩展,更加强壮和明确,关键是更加严谨。 BEM命名BEM的方法,可以确保参与网站开发的每一个人,都能够使用一个代码库并且使用同一种语言。使用BEM格式的命名规范,可以从容应对需求变更。 BEM是如何降低渲染过程中Style阶段耗时的?BEM不仅仅是一种CSS命名的方法论,它其实对于浏览器渲染页面的性能有帮助。 |
BEM命名
有一个好的样式指导手册将会显著提高开发的速度,debug的速度,以及在原有代码上完成新功能的效率。然而不幸的是,大多数的CSS 代码在开发过程中毫无任何结构和命名的规范。从长远角度来看,这会导致最后产生的CSS代码库很难维护。 BEM方法确保每一个参加了同一网站开发项目的人,基于一套代码规范去开发,这样非常有利于团队成员理解彼此的代码,而且对于后续接手项目的同学来说,也是一件好事。 我们将对Block,Element,Modifier从naming,html,css三个方面进行分析。
Block封装一个只对自己有意义的实体。当blocks能够被嵌套而且彼此之间可以交互的时候,语义上他们是等价的;没有层级关系。没有DOM表示的整体实体。(例如控制器和模型也可以是块) NamingBlock名字包含拉丁字母,数字和句号。当组合一个完整CSS class的时候,可以增加一个短的前缀:.block HTML任何DOM节点可以作为一个Block,只要它接受一个class名。 CSS
ElementBlock的一部分,当把它独立取出来时,没有任何实际意义。任何元素在语义上都是它自己的block紧密相连的。 NamingElement的名字可能包含拉丁字母,数字,句号以及下划线。CSS class名由block名成加两个下划线再加element的名字,最后组织成一个块名。 HTML任何的在Block中的DOM节点,都是一个element。在一个已知的block中,所有的element在语义上都是相等的。 <div class="block">
<span class="block__name"></span>
</div> CSS
Good .block__elem{color:#042}; Bad .block .block__elem {color:#042;}
div.block__elem {color:#042;} Modifierblock或者element的flag。使用他们可以改变样式,行为或者是状态。 NamingModifier的名字可以包含拉丁字母,数字,句号以及下划线。CSS的class可以由block或者element名称后面加--组成,例如.block--mod或者.block__elem--mod,以及.block--color-black .block--color-red。复杂的modifier里由短线替代空格。 HTMLModifier是一个额外的加在block或者element class名之后一个class 名。只为他们负责修改的blocks或者elements添加class,然后保持原有的class不变。 <div class="block block--mod">...</div>
<div class="block block--size-big block--shadow-yes">...</div> Bad <div class="block--mod">...</div> CSS
例子: <form class="form form--them-xmas form--simple"
<input class="form__input" type="text" />
<input class="form__submit form__submit--disabled" type="submit" />
</form> CSS: .form {}
.form--theme-xmas {}
.form--simple {}
.form__input {}
.form__submit {}
.form__submit--disabled {} |
BEM是如何降低渲染过程中Style阶段耗时的?我们知道浏览器渲染页面分为 因为BEM为每个元素都增加了单独的class,无须通过CSS选择器一级一级一级一直查找到最深的层级。BEM使得匹配元素的时间复杂度从O(n)降低到O(1)。 假设有这样的伪代码: function findElement(element) {
// complex css selectors cost O(n)
// BEM cost O(1)
} 注:如果对这一步骤有疑惑,可以查阅[译]Rendering Performance之Overview BEM是如何通过减少选择器的复杂性,从而降低computed style计算的损耗的?用一句话概括就是:通过一个特殊命名的class去替代复杂的选择器,降低浏览器在 style 阶段的性能损耗。 最简单的通过CSS去引用一个元素的方式只需要一个class: .title {
/* styles */
} 但是,随着项目的成长,会出现更加复杂的CSS,例如我们可能用下面这种选择器: .box:nth-last-child(-n+1) .title {
/* styles */
} 为了知道需要应用到浏览器的样式,必须这样问:“这是一个class名为title的元素,然后它的父元素需要找到第-n+1个class为box的元素?” .final-box-title {
/* styles */
} 我们需要花费一些时间去想class的名字,但是这对于浏览器来说会变得特别简单。 想知道更多Computed Style Calculation的信息,可以查看:[译]Rendering Performance之Reduce the Scope and Complexity of Style Calculations 为什么不适用语义化的标签而是直接去使用为块元素添加CSS class呢? |
在这篇【译】什么是CSS Modules ?我们为什么需要他们?的结尾处,明确指出CSS Modules不需要BEM,那么BEM到底是什么呢?
下面我将带领大家搞清楚前端领域的BEM到底是什么。
起初我以为BEM仅仅是一种项目内规范前端CSS命名的一种方法论,但后来才发现BEM原来其实还是一种性能优化的实践。
BEM降低了浏览器渲染过程
javascript->style->layout->paint->composite
中style阶段的选择器与元素之间的匹配消耗的时间。The text was updated successfully, but these errors were encountered: