日常的工作中,我们无时无刻不在和样式打交道。没有样式的页面就如同一部电影,被人随意地在不同地方做了截取。

BEM规范应该是对于我们现在前端组件开发中我觉得是最合适的一套范式了。所以,我在自己的日常工作中也是十分的推崇这样的一套CSS范式。

而自己最近也在看各种ui框架的源码,觉得ele对于这块还是处理的蛮好的,所以拿出来说说。

1.BEM

BEM是什么?

BEM范式我在以前自己的文章中简单的说过,就不再赘述了。

而我们来看看饿了么在BEM这块有着怎样的实践。

//element-ui
//config.scss
$namespace: 'el';
$element-separator: '__';
$modifier-separator: '--';
$state-prefix: 'is-';

element在config.scss里面定义了一些基础的配置项目,主要包括四个部分:

1.整套样式的命名空间,命名空间可以带来不用系统样式的隔离,当然缺点就是我们的样式一定是带有一个namespace的前缀出现

2.B和E之间的连接符

3.E和M之间的连接符

4.状态的前缀 ,因为有很多的用户行为而带来的激活这样的效果。在js中我们会说到is和as。一个是类型的判定,一个是类型的模糊,这是多态的特性体现。所以,同理的话,is在css中代表的就是当前元素状态的判定,例如:is-checked(是否被选中)之类等等

2.“B”的定义

@mixin b($block) {
$B: $namespace+'-'+$block !global; .#{$B} {
@content;
}
}

ele通过宏b来实现的BEM中B的定义

这里的话,我通过radio来作为假设。最后我们在b中通过!global提升了一个$B:el-radio。这也是我以前提到过的改良后的BEM。通过插值语句#{ }生成了 “.el-radio”。然后通过@content向生成的B中导入内容。

导入的内容就是通过调用宏b生成的所有的样式。

下面是所有通过mixin b可以生成的样式

//通过宏b生成的所有样式
@include b(radio) {
color: $--radio-color;
font-weight: $--radio-font-weight;
line-height:;
position: relative;
cursor: pointer;
display: inline-block;
white-space: nowrap;
outline: none;
font-size: $--font-size-base;
@include utils-user-select(none); @include when(bordered) {
padding: $--radio-bordered-padding;
border-radius: $--border-radius-base;
border: $--border-base;
box-sizing: border-box;
height: $--radio-bordered-height; &.is-checked {
border-color: $--color-primary;
} &.is-disabled {
cursor: not-allowed;
border-color: $--border-color-lighter;
} & + .el-radio.is-bordered {
margin-left: 10px;
}
} @include m(medium) {
&.is-bordered {
padding: $--radio-bordered-medium-padding;
border-radius: $--button-medium-border-radius;
height: $--radio-bordered-medium-height;
.el-radio__label {
font-size: $--button-medium-font-size;
}
.el-radio__inner {
height: $--radio-bordered-medium-input-height;
width: $--radio-bordered-medium-input-width;
}
}
}
@include m(small) {
&.is-bordered {
padding: $--radio-bordered-small-padding;
border-radius: $--button-small-border-radius;
height: $--radio-bordered-small-height;
.el-radio__label {
font-size: $--button-small-font-size;
}
.el-radio__inner {
height: $--radio-bordered-small-input-height;
width: $--radio-bordered-small-input-width;
}
}
}
@include m(mini) {
&.is-bordered {
padding: $--radio-bordered-mini-padding;
border-radius: $--button-mini-border-radius;
height: $--radio-bordered-mini-height;
.el-radio__label {
font-size: $--button-mini-font-size;
}
.el-radio__inner {
height: $--radio-bordered-mini-input-height;
width: $--radio-bordered-mini-input-width;
}
}
} & + .el-radio {
margin-left: 30px;
} @include e(input) {
white-space: nowrap;
cursor: pointer;
outline: none;
display: inline-block;
line-height:;
position: relative;
vertical-align: middle; @include when(disabled) {
.el-radio__inner {
background-color: $--radio-disabled-input-fill;
border-color: $--radio-disabled-input-border-color;
cursor: not-allowed; &::after {
cursor: not-allowed;
background-color: $--radio-disabled-icon-color;
} & + .el-radio__label {
cursor: not-allowed;
}
}
&.is-checked {
.el-radio__inner {
background-color: $--radio-disabled-checked-input-fill;
border-color: $--radio-disabled-checked-input-border-color; &::after {
background-color: $--radio-disabled-checked-icon-color;
}
}
}
& + span.el-radio__label {
color: $--color-text-placeholder;
cursor: not-allowed;
}
} @include when(checked) {
.el-radio__inner {
border-color: $--radio-checked-input-border-color;
background: $--radio-checked-icon-color; &::after {
transform: translate(-50%, -50%) scale(1);
}
} & + .el-radio__label {
color: $--radio-checked-text-color;
}
} @include when(focus) {
.el-radio__inner {
border-color: $--radio-input-border-color-hover;
}
}
}
@include e(inner) {
border: $--radio-input-border;
border-radius: $--radio-input-border-radius;
width: $--radio-input-width;
height: $--radio-input-height;
background-color: $--radio-input-fill;
position: relative;
cursor: pointer;
display: inline-block;
box-sizing: border-box; &:hover {
border-color: $--radio-input-border-color-hover;
} &::after {
width: 4px;
height: 4px;
border-radius: $--radio-input-border-radius;
background-color: $--color-white;
content: "";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) scale(0);
transition: transform .15s cubic-bezier(.71,-.46,.88,.6);
}
} @include e(original) {
opacity:;
outline: none;
position: absolute;
z-index: -1;
top:;
left:;
right:;
bottom:;
margin:;
} &:focus:not(.is-focus):not(:active){ /*获得焦点时 样式提醒*/
.el-radio__inner {
box-shadow: 0 0 2px 2px $--radio-input-border-color-hover;
}
} @include e(label) {
font-size: $--radio-font-size;
padding-left: 10px;
}
}

3.“E”的定义

完成了B以后的话,就要处理E了。不过在e中多做了两件事

1.通过each完成了"BE"的样式的生成,例如是input,那么$currentSelector就是".el-radio + __ +  input"

2.通过函数处理@return containsModifier($selector) or containWhenFlag($selector) or containPseudoClass($selector) 三种情况

@mixin e($element) {
$E: $element !global;
$selector: &;
$currentSelector: "";
@each $unit in $element {
$currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","};
} @if hitAllSpecialNestRule($selector) {
@at-root {
#{$selector} {
#{$currentSelector} {
@content;
}
}
}
} @else {
@at-root {
#{$currentSelector} {
@content;
}
}
}
}

4.“M”的定义

最后是m的生成,基本上原理都和前面说到的是一样的了。

例如:el-radio--medium。用来描述radio的size属性。那么$currentSelector就是".el-radio + -- +  medium"

@mixin m($modifier) {
$selector: &;
$currentSelector: "";
@each $unit in $modifier {
$currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","};
} @at-root {
#{$currentSelector} {
@content;
}
}
}

5.小结

我在这也就是抛砖引玉的说下,精彩的内容还是要大家自己去源码里看,或者自己去试着写一下那就是最好了。

试着写一个vue或者react的组件用上BEM范式去管理类名,肯定也会和我一样,觉得在基于组件化开发的前端项目中,BEM范式绝对是我们管理css的一把利器。

当然,在以后的文章中我也会来说说OO和SMA范式。

浅谈element-ui中的BEM范式实践的更多相关文章

  1. 浅谈关于QT中Webkit内核浏览器

    关于QT中Webkit内核浏览器是本文要介绍的内容,主要是来学习QT中webkit中浏览器的使用.提起WebKit,大家自然而然地想到浏览器.作为浏览器内部的主要构件,WebKit的主要工作是渲染.给 ...

  2. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  3. 转: 浅谈C/C++中的指针和数组(二)

    转自:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242419.html 浅谈C/C++中的指针和数组(二) 前面已经讨论了指针和数组 ...

  4. 转:浅谈C/C++中的指针和数组(一)

    再次读的时候实践了一下代码,结果和原文不一致 error C2372: 'p' : redefinition; different types of indirection 不同类型的间接寻址 /// ...

  5. 转载 浅谈C/C++中的static和extern关键字

    浅谈C/C++中的static和extern关键字 2011-04-21 16:57 海子 博客园 字号:T | T   static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.ext ...

  6. 浅谈C语言中的强符号、弱符号、强引用和弱引用

    摘自http://www.jb51.net/article/56924.htm 浅谈C语言中的强符号.弱符号.强引用和弱引用 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2014- ...

  7. 【sql注入】浅谈sql注入中的Post注入

    [sql注入]浅谈sql注入中的Post注入 本文来源:i春秋学院 00x01在许多交流群中,我看见很多朋友对于post注入很是迷茫,曾几何,我也是这样,因为我们都被复杂化了,想的太辅助了所以导致现在 ...

  8. Element UI 中组件this.$message报错

    最近在做毕设的时候,用Element UI中的消息提示message一直报以下的错误: 展示的效果也不好看,没有图标什么的: 但我明明有在main.js引入了element-ui 呀,因为毕设时间很赶 ...

  9. [原创]浅谈Web UI自动化测试

    [原创]浅谈Web UI自动化测试 Web UI自动化测试相信大家都不陌生,今天来谈谈这个,我最早接触自动化测试时大约是在2004年,2006年当时在腾讯财付通算是开始正式接触自动化测试,之所以是正式 ...

随机推荐

  1. IIS易混概念小结

    IIS连接数 常识: 虚拟主机会限制IIS连接数,关于其含义,差不多每个主机供应商都有一套自己的说法,微软也没有给出很明确的解释: 含义: IIS服务器可以同时容纳客户请求的最高连接数,准确的说应该叫 ...

  2. hdu5988 Coding Contest

    首先这是个费用流,用log转乘法为加法,外加模板的修改,需加eps 下面是废话,最好别看 闲来无事(鼓起勇气)写这篇博客 这是个自带影像回访的题目 青岛的炼铜之旅,大学的acm生涯就这样结束了.或许还 ...

  3. 最新数组方法(包括es6)

    整理目前所用过的数组方法,学习了新增的es6方法. 1 arr.push() 从后面添加元素,返回值为添加完后的数组的长度 let arr = [1,2,3,4,5] console.log(arr. ...

  4. 在ASP.NET 中检测手机浏览器(转)

    引言 之前做的项目中需要在浏览器查看PDF文件.在电脑端没有问题,但是手机端网页打开失败. 后来使用了pdf.js,个人认为pdf.js的页面不够清爽,就希望网站能自动检测登录设备,电脑端保持原样,手 ...

  5. 关于工作中Git相关的总结

    来公司一周多,主要是在熟悉各种环境和流程,而作为研发来讲,git的使用也是必不可少的.以前使用方式单一,几个人对着master,pull和push,来了之后发现其实在日常的开发中,git可以很方便的帮 ...

  6. C# Hook原理及EasyHook简易教程

    前言 在说C# Hook之前,我们先来说说什么是Hook技术.相信大家都接触过外挂,不管是修改游戏客户端的也好,盗取密码的也罢,它们都是如何实现的呢? 实际上,Windows平台是基于事件驱动机制的, ...

  7. jxl 导出数据到excel

    优点: Jxl对中文支持非常好,操作简单,方法看名知意. Jxl是纯javaAPI,在跨平台上表现的非常完美,代码可以再windows或者Linux上运行而无需重新编写 支持Excel 95-2000 ...

  8. Django用户登录与注册系统

    一.创建项目 1.1.创建项目和app python manage.py startproject mysite_login python manage.py startapp login 1.2.设 ...

  9. Problem : 1008 ( Elevator )

    好操蛋啊,电梯竟然能原地不动,你大爷的,这逻辑,太弱智了.... Problem : 1008 ( Elevator )     Judge Status : Accepted RunId : 103 ...

  10. openstack安装系列问题:window7 64位安装的virtualBox 只能选择32位的系统安装不能选择64位的系统安装

    个人原创,转载请注明作者,出处,否则依法追究法律责任 2017-10-03-12:22:22 现象:window7 64位安装的virtualBox 只能选择32位的系统安装不能选择64位的系统安装 ...