特别声明:此篇文章由David根据《Block, Element, Modifier》进行翻译,整个译文带有我们自己的理解与思想,如果译得不好或不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://bem.info/method/definitions/以及作者相关信息

——作者:BEM官网

——译者:David

什么是BEM?

BEM代表块(Block),元素(Element),修饰符(Modifier)。这些术语的含意将在本文进一步阐述。

编程方法论中一个最常见的例子就是面向对象编程(OOP)。这一编程范例出现在许多语言中。在某种程度上,BEM和OOP是相似的。它是一种用代码和一系列模式来描述现实情况的方法,它只考虑程序实体而无所谓使用什么编程语言。

我们使用BEM的原则创建了一个前端开发技巧和工具的集合,这样我们就能快速构建一个网站,并且保证他们长久的可维护性。

统一数据域

想象一个如下图所示的普通网站。

就这样的一个网站来说,指出它是由哪些“块”构成的,对开发是很有帮助的。

例如,在上图中有Head,Main Layout和Foot块。Head由Logo,Search,Auth块和Menu组成。MainLayout包括一个Page Title和一个Text块。

对于团队沟通来说给页面的每一部分起个名字是很有用的。

这样的话一个项目经理就可以这么说:

让Head再大点;

创建一个Head中不带Search的页面。

一个HTML开发人员可以对一个JavaScript开发人员说:

给Auth块来点动画,等等

现在让我们仔细了解一下什么是BEM:

块(Block)

一个块是一个独立的实体,就像应用的一块“积木”。一个块既可以是简单的也可以是复合的(包含其他块)。

例如搜索表单块:

元素(Element)

一个元素是块的一部分,具有某种功能。元素是依赖上下文的:它们只有处于他们应该属于的块的上下文中时才是有意义的。

例如一个输入域和一个按钮是Search块的中的元素。

描述页面和模板的意义

块和元素构成了页面的内容。它们不仅仅是被呈现在一个页面上,它们的排列顺序也同样重要。

块(或元素)彼此之间可能遵循着某种顺序。

例如,电商网站上的一个商品列表:

……或者菜单项:

块里也有可能再嵌套块。

例如,一个Head块会包含其他块:

除了我们自己创建的一些块之外 ,我们还需要一种途径来描述页面上那些纯文本的布局。为此,每一个块和元素都应该有一个可以识别的关键字。

用来标识一个具体块的关键字其实就是这个块的名字(block name)。

例如,menu可以作为Menu块的关键字,head可以作为Head块的关键字。

用来标识一个元素的关键字也是这个元素的名字。

例如,菜单中的每个菜单项就是menu块的item元素。

一个项目中的块名必须是唯一的,明确指出它所描述的是哪个块。相同块的实例可以有相同的名字。在这种情况下一个块在一个页面上可以出现2(3,4,……)次。

一个块范围内的一种元素的名字也必须是唯一的。一种元素可以重复出现多次。

例如,菜单项:

关键字应该按一定的顺序摆放。任何支持嵌套的数据格式(XML,JSON)都可以:

Search

在这个例子中,b和e两个命名空间用来区分块和元素两种节点。

同样可以用JSON格式来表示:

{

block: 'page',

content: {

block: 'head',

content: [

{ block: 'menu', content: … },

{

elem: 'column',

content: { block: 'logo' }

},

{

elem: 'column',

content: [

{

block: 'search',

content: [

{ elem: 'input' },

{ elem: 'button', content: 'Search' }

]

}

]

},

{

elem: 'column',

content: {

block: 'auth', content: …

}

}

]

}

}

上面的例子展示了一个块和元素相互嵌套的对象模型。这个结构中也可以包含任意多的自定义数据字段。

我们把这种结构叫BEM树(和DOM树类似)。

通过把模板转换(使用XSL或是JavaScript)应用到BEM树上生成最终的浏览器标签。

如果开发人员需要把一个块移动到页面的其他地方,他只需要改变一下BEM树就好了。模板会生成最终的视图。

你可以使用任何格式来描述BEM树,也可以使用任何模板引擎。

我们把JSON作为页面的描述格式。然后通过一个基于JS的模板引擎BEMHTML来把它转换为HTML。

块的独立性

随着一个项目的发展,我们常常会在页面中添加,删除,或者是移动一些块。例如,你可能想要互换Logo和Auth块,或者把Menu放到Search块下面。

为了让这个过程更加简化,块必须是独立的。

一个独立的块可以放置在页面的任意位置 ,包括嵌套在其他块里。

独立的CSS

从CSS的角度来看:

一个块(或者一个元素)必须有一个唯一的“名字”(一个CSS类)这样才能被CSS规则所作用。

HTML元素不能用作CSS选择器(如.menu td)因为这样的选择器并非是完全上下文无关的。

避免使用级联(cascading)选择器(译注:如.menu .item)。

为独立的CSS类命名

下面是一种可能的CSS类命名方案:

一个块的CSS类名就是这个块的名字(block name)。

...

一个元素的CSS类名是一个块名和一个元素名的组合,它们中间用一些符号隔开。

在一个元素的CSS类名中包含一个块名是必要的,这样可以让级联最小化。

我们在长名称中使用连字符分隔单词(例如,block-name),使用两个下划线来分隔块名和元素名(block-name__element-name)。

例如:

block-name--element-name

blockName-elementName

独立的模板

对于模板引擎来说,块的独立性意味着:

输入的数据要描述清楚块和元素:块(或元素)必须有个唯一的“名字”,在模板中告诉我们诸如“Menu应该放到这里”这样的事情。

块可以出现在BEM树的任意地方。

独立块模板

当模板引擎在某个模板中遇到一个块的时候可以准确地把这个块转换成HTML。因此每个块都应该有自己的模板。

例如,下面就是一个XSL模板:

我们的产品正在逐渐弃用XSLT,我们用我们自己开发的基于JavaScript的模板引擎XJST来解析它。这个模板引擎吸收了所有XSLT的优点(我们是声明性编程的粉丝),并且在服务端和客户端都可以用JavaScript来实现。

现在我们用一种叫做BEMHTML的特定领域语言来编写我们的模板,它是基于XJST的。BEMHTML的主要思想在Ya.Ru(在俄罗斯)的BEM俱乐部里提出。

块的重复

一个网站的第二个Menu块可能出现在Foot块里。或者,一个Text会变成两个,中间被一个广告分开。

即使一个块被开发成单独的单元,那么相同的块也可能在任何时候出现在这个页面上。

在CSS相关的术语中,这意味着:

一定不能使用ID选择器:只有类选择器才能满足我们非唯一性的需求

在JavaScript里意味着:

可以准确地检测到具有相同行为的块,因为它们有相同的CSS类名:使用CSS类选择器,可以拣选出所有相同名字的块,方便给它们定义动态行为

块修饰符

我们经常需要创建一个和已存在的块非常相似的块,只是外观或行为有些许改变。

比如说我们有一个这样的任务:

给Footer添加另外一个布局不一样的Menu。

为了避免开发一个和现有的块只稍微有点不同的另一个块,我们引入修饰符(modifier)的概念。

修饰符作为一个块或是一个元素的一种属性,代表这个块或这个元素在外观或是行为上的改变。

一个修饰符有一个名字和一个值。多个修饰符可以同时使用。

例如:一个用来指定背景颜色的块修饰符

例如:一个改变“当前”选项的元素修饰符

从输入数据的角度来看修饰符

在BEM树里,修饰符是用来描述一个块或者是一个元素实体的属性的。

例如,它们可以作为XML的属性节点:

用JSON也可以:

{

block: 'menu',

mods: [

{ size: 'big' },

{ type: 'buttons' }

]

}

从HTML/CSS的角度来看修饰符

对于一个块或者是一个元素来说修饰符是一个附加的CSS类。

.menu_size_big {

// CSS code to specify height

}

.menu_type_buttons .menu__item {

// CSS code to change item's look

}

我们用一个下划线来分隔块名(或元素名)和修饰符名,再用另一个下划线来分隔修饰符名和它对应的值。(译注:此处原文是俄文,大致就是这个意思)。

元素修饰符

元素修饰符以相同的方式实现。

当手写CSS代码的时候,为了编程的可访问性,始终使用分隔符非常重要。

例如,当前菜单项就可能被一个修饰符标记:

Index

Products

Contact

{

block: 'menu',

content: [

{ elem: 'item', content: 'Index' },

{

elem: 'item',

mods: { 'state' : 'current' },

content: 'Products'

},

{ elem: 'item', content: 'Contact' }

]

}

.menu__item_state_current

{

font-weight: bold;

}

上面的结构在HTML中代表如下:

  • Index
  • Products
  • Contact

或使菜单类独立于它布局的实现细节之外:

  • Index
  • Products
  • Contact
Index
Products
Contact

主题抽象

当许多人开发同一个项目他们应该在数据域上保持一致,在给块和元素命名的时候用上它。例如,一个标签云的块始终命名为tags。其中的每个元素就是一个tag。这种约定贯穿所有的语言:CSS,JavaScript,XSL等等。

从开发处理的角度来看:所有参与都基于同样的约定 。

从CSS角度开看:• 块和元素的CSS可以写成一种伪代码,然后根据命名约定编译成CSS。

.menu {

__layout {

display: inline;

}

__layout-item {

display: inline-block;

}

__item {

_state_current {

font-weight: bold;

}

}

}

相应JavaScript:可以使用专门的辅助库来替代使用类名直接选择DOM元素:

$('menu__item').click( … );

$('menu__item').addClass('menu__item_state_current');

$('menu').toggle('menu_size_big').toggle('menu_size_small');

块和元素的CSS类命名约定可能在一段时间内发生改变。如果命名约定改变了,只需要修改那些要访问块和元素,以及可能处理它们的修饰符的方法(function)。

block('menu').elem('item').click( … );

block('menu').elem('item').setMod('state', 'current');

block('menu').toggleMod('size', 'big', 'small');

上面的代码是抽象的,现实中我们使用bem-bl块中的i-bem块的JavaScript核心和库。

块的一致性

一个网站有一个带有某种动态行为的Button块。

当鼠标滑过这样的块,它的外观就会改变。

经理可能会要求在别的页面也使用相同的按钮。

一个块光有CSS实现还是不够的。复用一个块也意味着复用它的行为,也就是它所绑定的JavaScript。

所以一个块必须“知道”关于它自己的一切。为了实现一个块,要用我们所用到的所有技术来描述清楚它的外观和行为,我们把这叫多语言机制。

多语言描述一个块的时候涉及实现这个块的外观和功能的所有编程语言(技术)。

想让一个块像一个UI元素一样展现在页面上,我们需要用下面这些技术来实现它:

模板(XSL,TT2,JavaScript等等),把块的声明转换成HTML代码

CSS,描述块的外观

JavaScript,如果块有动态行为的话

图片

文档

构成一个块的每样东西都可以作为一种块技术。

真实案例

Yandex是一个大公司(在俄罗斯),它使用BEM方法论来开发它的服务。

BEM方法论并不要求你使用某种框架。你也不必在你用到的所有页面技术中都使用BEM(但是那会是最有效的)。

Yandex的所有服务都在它们页面的CSS和JavaScript代码以及XSL模板中用到了BEM。例如:

一此服务并没有使用XSL模板而是使用我们最新的模板技术来构建他们的页面。就是我们前面提到的BEMHTML模板引擎。以下就是这些服务:

也有一些其他公司在使用BEM。

比如,mail.us就在他们的部分服务中用到了BEM。他们页面上的一些块的CSS代码就是基于BEM的。他们也有自己的C++模板引擎,并根据BEM方法论来编写块模板。

更多的案例:

你或许也对那些使用bem-bl块库的网站感兴趣:

了解更多

译者手语:整个翻译依照原文线路进行,并在翻译过程略加了个人对技术的理解。如果翻译有不对之处,还烦请同行朋友指点。谢谢!

关于David

2009年开始接触前端开发,2011年组建创业团队——[五维互动],2012年团队被“收编”并更名[创影互动],遂只身来上海发展,现在就职于FlipScript。欢迎交流共勉:腾讯微博、个人博客。

如需转载烦请注明出处:

bem什么意思_BEM的定义相关推荐

  1. bem什么意思_BEM是什么?

    BEM的含义 1.BEM是业务事件管理(business event management)的缩写. BEM是能够让机器在业务流程出现问题时迅速做出反应,提醒人们重新回到正确轨道上的一种方法. 从Fo ...

  2. bem什么意思_BEM命名法

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

  3. bem什么意思_bem是什么意思_bem的翻译_音标_读音_用法_例句_爱词霸在线词典

    全部 Methods Three different concentrations of the n - butanol extract of MOH ( BEM ) : 0.038 g · L ~ ...

  4. bem什么意思_bem

    In a year or so, Bem coolly suggests, we may have to agree with the Queen. 本冷静地提出,一两年后,我们可能会被迫同意女王的观 ...

  5. bem什么意思_BEM思想之彻底弄清BEM语法

    人们问我最多的问题之一是在CSS类名中"--"和"__"是什么意思?它们的出现是源于BEM和Nicolas Gallagher... BEM的意思就是块(blo ...

  6. bem什么意思_BEM是什么意思

    1. This method has the advantages of both FEM and BEM, which can be seen in its engineering applicat ...

  7. bem什么意思_BEM规范你应该了解

    作者的话 这几天一直在忙着公司网站标准版的前台页面模块化,大面积的书写css代码,然后发现规范不同意,命名不规范导致的问题确实会很严重,极大影响了开发效率,刚好今天又看到了这个关于css的bem规范, ...

  8. bem什么意思_BEM是什么意思中文翻译

    音标:abbr.British Empire Meda不列颠帝国勋章 网络边界元:边界元法:边界单元法:边界元方法 网络释义 1 . 边界元 Time domain BEMfor wave propa ...

  9. qblade安装及学习

    文章目录 1 下载安装网址 2 学习视频 3翼型设计 4 叶片设计 5 仿真分析--基于bem分析 6结构设计与仿真 7风场创建 8 非线性提升模拟 1 下载安装网址 https://sourcefo ...

最新文章

  1. WinForm下PictureBox和Panel控件的On_Paint事件有何区别
  2. 提取LSA密码lsadump
  3. [转载]永远保持随时可以离开的能力(不仅仅是张泉灵)
  4. MySQL数据备份方式,及热备与冷备的优缺点
  5. ISE简介及其下载 安装 和谐 与 卸载
  6. 总结了一些指针易出错的常见问题(二)
  7. 【计算机算法设计与分析】——5.4最优二分检索树
  8. uni-app清理缓存数据_数据清理-从哪里开始?
  9. openstack实例状态错误_Openstack虚机操作总结
  10. 测试工程师需要具备的技能
  11. 受疫情影响 蔚来整车生产已经暂停
  12. dedecms 5.7 站点文件从本地子目录上传到远程根目录后找不到模板的解决方案
  13. win7为什么打开桌面上的计算机很卡很慢,如何解决win7系统电脑反应慢
  14. WM_TIMER消息在线程被阻塞时的系统处理
  15. mysql 无限上级_mysql无限上级
  16. Keras验证集切分
  17. linux spdbv教程,计算机化学实践基础教程
  18. 大数据对人们生活的影响有哪些
  19. Go 标准库介绍一: Replacer
  20. simpleBGC32-软件代码开源

热门文章

  1. 解决qt.qpa.plugin: Could not load the Qt platform plugin “xcb“ in ““ even though it was found.
  2. uni-app商城中的搜索功能
  3. 语音识别项目简历收集-----机器学习(仅供参考)
  4. 可视化三维建模在线vr模型展示3d数字孪生系统
  5. 简易音乐播放器(js,html,css实现)
  6. 腾讯大讲堂之精益设计
  7. 微信小程序真机调试数据不显示
  8. List中根据对象字段快速查找对象
  9. [记错]weblogic启动是报错***/AdminServer.lok. Server may already be running
  10. 利用Python画一朵鲜艳的玫瑰花