问答:如何规划CSS 中 的命名方式 如何看待 CSS 中 BEM 的命名方式?

好多盆友 很纠结 css命名规则 怎么弄,还没起步就被绊住了,那么今天蝈蝈就针对这个问题来讨论一下 没什么技术

含量,但却对效率开发至关重要的
“问题”。

下文是一些知乎大神的个人经验总结,如果觉得有用请点赞 留言!

JS前端实用开发QQ群 :147250970  欢迎加入~!

如何看待 CSS 中 BEM 的命名方式?

BEM的意思就是块(block)、元素(element)、修饰符(modifier),是由Yandex团队提出的一种CSS
Class 命名方法。

类似于:

.block{}
.block__element{}
.block--modifier{}

再烂的东西,如果真的毫无价值,是会马上被历史所淹没的

每个领域都有沉淀下来对特定开发者在特定场景有用的东西

很赞同克军那句取其精华去其糟粕,何为精华,自己根据使用场景取舍

可能大多数同学看到那么多下划线中划线以及那么长我靠还有驼峰的名字,就会觉得混乱和不爽

不爽是一个很主观的词儿,他除了解决心理问题,没法解决生理问题

CSS这么多年并没有一个相对比较严谨的套路出来,宽松的写法导致团队成员写法各异,丢在页面都能跑起来,但混着做项目就不敢动或理不清别人写的代码

"这个CSS重写一遍比修改老文件快",这样的念头几乎所有人都曾有过.

我们团队用BEM快1年,下面我来谈谈一些心得

了解什么是 B.E.M

Block

!误区:这个block并非inline-block里的block,

而是将所有东西都划分为一个独立的模块,一个header是block,header里嵌套的搜索框是block,甚至一个icon一个logo也是block

block可以相互嵌套

Element

!误区:如果一个Element-son是另一个Element-father的子元素,

那么写法是 Block__Element-father__Element-son_Modifer,嵌套多了会很长么?

不是的!!!

一个Block下的所有Element无论相互层级如何,都要摊开扁平的属于Block

所以 BEM 最多只有 B+E+M 三级,不可能出现 B+E+E+..+E+M 超长class名,也要求E不能同名

Modifier

之前我们经常写的 .current .active 等表达状态

从Class中解读B.E.M

我们常说CSS的注释要写WHY,而不是写WHAT,看Class命名最好就知道是WHAT

BEM提出的一个概念是用连接符号来表达,它并不规定必须用什么连接符,但规定用不同连接符做团队内约定区分BEM 3类元素

例如我们组内约定

__双下划线代表B和E连接例如 menu__item

_单下划线代表B和M或E和M的连接 例如 menu_active 或 menu__item_active

-中划线同英语里做连字符例如 mod-menu 或 mod-menu__item 这里 B或E或M需要多个单词来描述,就使用中划线

打字会抽搐吧...

你听说过Emmet么?再不济Zen Coding有听说过吧?实在不行听说过安利也行啊

FYI http://docs.emmet.io/filters/bem/

拆分Block到文件

我们并没有用BEM推荐的拆分CSS到更多目录里,图片是拆目录的.因为用的是 Grunt+LESS

团队项目特色为N个相互独立的移动端项目,Block并不会很多,所以文件扁平化很直观,带来的效率也相对高,如图为其中某个项目的css部分

另外,写block的时候需要新建less文件,字母排序,是否重名都很清晰

按ctrl+f查找class定位和按快捷键打开文件名没啥大区别,更何况新版LESS还有source map

最后我们团队正在开发对应模块管理的工具,目标是向NPM一样玩,同Alice一样规划解决方案

代码复用

代码风格可能文档里说的也不是很详细,不如直接对着他们的页面按F12吧 http://beta.yandex.com/

BEM/OOCSS 风格对维护重用的class有极大帮助,适当的拆分block后组合,威力无穷

那个千年老栗子——如果我想将一个f30的类,改成f35怎么办?是挂羊头卖狗肉的直接将.f30{font-size:30px}改成.f30{font-size:35}吗?还是要进行全局搜索,改动所有的html的class名?

或者 Alice 里面的

.text-size30{font-size:30px;}

.text-size20{font-size:20px;}

.text-size10{font-size:10px;}

而我们采用的是类似 bootstrap 的方案

用程度来划分,而非具体数值,所以根本就不会存在.text-size30这么个类,那个写style上去有毛线区别.

在var.less里定义具体的数值

在 ui.less 里调用

BEM的任何一个block都可以到处用,这对模块并不多的手机项目非常有利.

关于hax大神吐槽的不用ID和后代选择器

ID

ID对于我和!important对于我一样,并不否认价值,但想不起来上一次用是啥时候了.

说到这里顺便提一下 z-index的问题,有多少同学写z-index的时候会写1000+?有做过整站z-index规划么? 同样的用 class 如果能规划好了,我是不倾向用id,也想不到有什么非用ID不可的情况,性能什么的,呵呵,测过,影响不大

特定场景例子:在腾讯,JS和CSS是分别2种团队的人在写,我们约定ID给JS,class给CSS和固定前缀的JS hook,不管是不是BEM,ID在我们这两种团队约定下也是不使用,并且也没带来啥问题

后代选择器

这个BEM写block的时候是不用,但block相互嵌套的时候是用的,

例如一个状态下需要变动多个表现,用后代选择器一次性处理

性能以及JS/CSS代码可维护性都有明显优势

节选自
http://yandex.st/search_islands_www/0.2.15/desktop.bundles/index/_index.css

Tag selector 是翻译成标签选择器么

BEM是不允许用标签选择器的,一开始难以接受...

.menu li 能搞定的事情需要每个 li 都写.menu-item

坏处

是 k 数增加么?gzip下真不是个问题,或者是写代码额外工作量?这难道不是动态生成的么?再不济编辑器也可以随便列编辑或复制当前行或代码提示啊

好处

就是避免 li 里的 li 受影响

举个例子,商品详情页是允许商家自定义标签的,那么商家展示区域标签的祖先元素一旦用标签选择器定义了样式,子子孙孙都要背负.

所以十分赞同在无法百分百确定不会嵌套同样标签的情况下不用标签选择器

团队最重要的是统一

有一次讨论连字符用中划线还是下划线的时候,谁也说服不了谁,

最后一个掌勺的拍板,大家统一用一个,而非同一个团队多种风格.

这对上下游合作,内部合作都会极大的降低沟通成本

之所以用 BEM(部分),也是因为没找到更好的类似规范,虽然有缺陷,但至少可以统一

讨论一个东西,我们很容易找出他的槽点,但是提出更好解决方案的同学少之又少,

从BEM中我们可以学习他优秀的方面纳为己用,

团队合作永远是统一高于一切

张克军,豆瓣前端工程师

SCSS让CSS变的更像编程语言。于是,很自然的改变了CSS的传统组织方式。

关于BEM争议最大的就是它的命名风格,这样:

<ul class="block-name">

<li class="block-name--element-name">…</li>

<li class="block-name--element-name">…</li>

</ul>

block + element + modifier,鼓励一级一级的写的非常具体,很长。

问题:

1. 这么长,影响书写效率吧。肯定会影响但这是个很大的问题吗(自动提示会缓解一些)

2. html和css的size肯定会大一些。size大的顾虑是影响传输,在gzip面前可以忽略

3. 不爽。的确很违背习惯,但任何个人喜好和习惯作借囗都不职业

风格不重要。我更关心它的好处:

1. SCSS嵌套过多。超过3层就很难阅读了。

2. 嵌套多,选择器的层级就会多,性能不知不觉变差

3. 复用。这么长的名,想冲突都难

还有一个代码设计上的原则,不暴露抽象类。举例:

以前:

<ul class="list list-member">

<li>xxx</li>

</ul>

.list是抽象的列表类。层叠的.list-member类,定义少量样类就可以实现一个成员列表的样式。

但是在其它编程语言里抽象类是不会被暴露出来的。借鉴BEM会是这样:

<ul class="member-list">

<li class="member-list__item">xxx</li>

</ul>

不在html里层叠抽象类,而是在SCSS里继承:

%list { ... }

.member-list {

@extend %list;

}

.member-list__item {

// 不同的样式规则

}

这样更符合编程的特点。重要的是在维护上。假如变样了需要继承另一个抽象类,不需要改html,只要改css。这样SoC更彻底。

风格无非是某种形式,可以约束人做到一致。背后的设计思想才值得应用。如果用BEM的风格,但没做到抽象类的封装,没做到选择器的扁平,那就是失败的应用。

最后,我非常认同这种设计思想。但我还是不会照搬它的命名规则。太TM囧了!

最后我吐槽一句:我的这篇博文 排版 真tmd恶心啊!

时间: 2024-10-11 04:42:43

问答:如何规划CSS 中 的命名方式 如何看待 CSS 中 BEM 的命名方式?的相关文章

HTML中放置CSS的三种方式和CSS选择器

(一)在HTML中使用CSS样式的方式一般有三种: 1 内联引用 2 内部引用 3 外部引用. 第一种:内联引用(也叫行内引用) 就是把CSS样式直接作用在HTML标签中. <p style="font-size: 10px; color: #FFFFFF;"> 使用CSS内联引用表现段落. </p> 特点:内联的样式比其他方法更加灵活,但需要和展示的内容混淆在一起,内联样式会失去一些样式表的优点. 第二种:内部引用(也叫内嵌式) 使用style标签直接把CSS

[ css 深入理解 vertical-align line-height 属性 ] css中深入理解vertical-align和line-height的基友关系及实例演示的区别

一.想死你们了 几个星期没有写文章了,好忙好痒:个把月没有写长篇了,好忙好想:半个季度没在文章中唠嗑了,好痒好想. 后面一栋楼有对夫妻在吵架,声音雄浑有力,交锋酣畅淋漓,还以为只有小乡镇才有这架势,哦,突然想起来,我就是住在上海郊外的小乡镇上. 刚刚买了几十股京东的股票,第一次玩这个,看好京东的发展.其实股价21的时候就打算入手了,但是,转外汇的时候,提示,要工作时间.然后一忙二忘,等现在入的时候,已经涨了20%多了,科科,肥皂弄人啊!写到这里的时候,忍不住拿出手机一看,哎呦,不错哦,盈利28刀

CSS的class、id、css文件名的常用命名规则

(一)常用的CSS命名规则 头:header 内容:content/container 尾:footer 导航:nav 侧栏:sidebar 栏目:column 页面外围控制整体布局宽度:wrapper 左右中:left right center 登录条:loginbar 标志:logo 广告:banner 页面主体:main 热点:hot 新闻:news 下载:download 子导航:subnav精心开发5年的UI前端框架! 菜单:menu 子菜单:submenu 搜索:search 友情链

解决MVC中使用BundleConfig.RegisterBundles引用Css及js文件发布后丢失的问题

ASP.NET MVC4,ASP.NET MVC5中对JS和CSS的引用又做了一次变化,在MVC3中我们这样引用资源文件: <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> 将在运行的时候自动将虚拟(相对)路径转换为应用程序绝对路径.这是比较传统的引用方式,尽管他做了一次转换操作,对服务器的请求数量

AngularJS中实现显示或隐藏动画效果的3种方式

本篇体验在AngularJS中实现在"显示/隐藏"这2种状态切换间添加动画效果. 通过CSS方式实现显示/隐藏动画效果 思路: →npm install angular-animage→依赖:var app = angular.module("app",["ngAnimate"]);→controller中一个变量接收bool值→界面中提供一个按钮,点击改变bool值→界面中显示/隐藏的区域提供ng-if和controller中的bool值绑定

Django中加载js和css文件

Django中加载js和css文件 项目的目录结构如下: mysite |-mysite |-|-static |-|---js和css文件 |-|-|-init.py |-| |-models.py |-| |-views.py |-|-init.py |-|-settings.py |-|-urls.py |-templates |-|-(template html 文件) settings.py中static变量的设置: STATIC_ROOT = os.path.join(os.path

table中tr使用toggle不好,选择换一张方式

好几次遇到的问题,都是table中tr后面有一部分内容要显示,也是用tr装的,但是需要点击该行,后面那个tr才显示出来.不过最好不要用toggle去写,因为着实效果不佳.故而建议换一种方式,也许最简单的js才是最有效的. <html xmlns="http://www.w3.org/1999/xhtml" > <head> <meta http-equiv="Content-Type" content="text/html;

Selenium自动化中DOM,XPATH,CSS定位Web页面对象的优劣性分析

加速IE浏览器自动化执行效率:Selenium自动化中DOM,XPATH,CSS定位Web页面对象的优劣性分析 1.技术背景       在Web应用中,用户通过键盘在输入框中输入值和鼠标点击按钮,链接等.比如在用户名输入框和密码输入框输入正确的用户名和密码,然后点击登录按钮进行登录.在Selenium自动化中,Selenium提供多种API来对HTML元素进行操作,对于每个HTML元素,需要一个可以标识它的标识符,在Selenium中称之为定位器,Selenium支持多种不同类型的定位器,有标

谷歌浏览器修改CSS和js后同步保存到文件中 (译)

谷歌浏览器修改CSS和js后同步保存到文件中. 英文原文:http://www.stephensaw.me/google-chrome-devtools-source-maps/ 谷歌的Chrome DevTools源地图 谷歌的Chrome DevTools发展得越来越好,尤其是他们快速的Blink and V8的性能 ,而且他们使DevTools更好. 最近我发现,编辑源代码的正确的方式是使用源映射了Chrome DevTools. Source Maps 要验证源地图的开启,转至DevTo