使用实践
保证各个部分只有一级 BEM,原则上不会出现2层以上选择器嵌套
修饰器需要和对应的块或元素一起使用,避免单独使用。
<ul class="l-grid"><li class="l-grid__item"><div class="c-card"><div class="c-card__header"></div><div class="c-card__body"></div></div></li></ul>
<div class="mk-collapse"><div class="mk-collapse-item mk-collapse-item--expanded"><!--对于折叠面板的header 层,我们可以划分一个单元格组件 mk-cell 组件 减少嵌套,当前层级可加mk-collapse-item__title class建立关联,后续的子元素归于mk-cell的层级,后续mk-cell也可独立在其他地方复用--><divclass="mk-cell mk-collapse-item__title "><div class="mk-cell__title"><span>标题1</span></div><i class="mk-icon mk-cell__right-icon"></i></div><!--对于分割线这类常规公告样式,我们可以直接用class ,独立出来,不必可以建立关联--><div class="divider"></div><div class="mk-collapse-item__wrapper"><div class="mk-collapse-item__content">Hello World</div></div></div></div>
BEM函数
$namespace: 'el'; //前缀名$element-separator: '__'; //子元素连接符$modifier-separator: '--'; //块样式状态连接符$state-prefix: 'is-'; //特定状态列前缀
/* BEM-------------------------- */@mixin b($block) {$B: $namespace+'-'+$block !global;.#{$B} {@content;}}@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;}}}}@mixin m($modifier) {$selector: &;$currentSelector: "";@each $unit in $modifier {$currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","};}@at-root {#{$currentSelector} {@content;}}}
B
@mixin b($block) {$B: $namespace+'-'+$block !global; //变量拼接形成对应格式的class;再使用!global将其提升为全局变量.#{$B} {@content; // 使用混合;大括号后定义的样式将都会解析到这里}}
E
@mixin e($element) {$E: $element !global;$selector: &;$currentSelector: "";@each $unit in $element {$currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","};}//实际上@each内 其实就是变量拼接,通过__符连接父级选择器和传入的子元素,//而传入的值可以是一个,也可以是数组//判断父级选择器是否包含'--' 'is-' ':'@if hitAllSpecialNestRule($selector) {@at-root {#{$selector} {#{$currentSelector} {@content;}}}} @else {@at-root {#{$currentSelector} {@content;}}}}
例子:
//执行混合;b方法的定义在这里就不重复写了@include b((card)) {border-radius: 4px;border: 1px solid #ebeef5;background-color: #fff;overflow: hidden;color: #303133;transition: 0.3s;@include e(footer) { //传入单个padding: 20px;}@include e((title, body)) { //传入数组padding: 20px;}}//编译后.mk-card .mk-card__footer { //传入单个编译结果content: "11";padding: 20px;}.mk-card .mk-card__title, //传入数组编译结果.mk-card .mk-card__body {content: "11";padding: 20px;}
例子:
// 不含"--"、"is-"、 ":" 编译前 不包含,则通过@at-root跳出选择器嵌套.mk-card{$selector: &;@include e(footer) {//传入单个padding: 20px;}}// 编译后.mk-card__footer {padding: 20px;}// 含"--"、"is-"、 ":" 编译前 ;包含则嵌套于父级选择器下.mk-card:hover {$selector: &;@include e(footer) {//传入单个padding: 20px;}}//编译后.mk-card:hover .mk-card__footer {padding: 20px;}
M
@mixin m($modifier) {$selector: &;$currentSelector: "";@each $unit in $modifier {$currentSelector: #{$currentSelector +& +$modifier-separator +$unit +","};}@at-root {#{$currentSelector} {@content;}}}
例子:
//编译前@include b(card) {border-radius: 4px;border: 1px solid #ebeef5;background-color: #fff;overflow: hidden;color: #303133;transition: 0.3s;@include e(footer) {//传入单个padding: 20px;}@include m(primary) {background: #409eff;}}//编译后.mk-card {border-radius: 4px;border: 1px solid #ebeef5;background-color: #fff;overflow: hidden;color: #303133;-webkit-transition: 0.3s;transition: 0.3s;}.mk-card__footer {padding: 20px;}.mk-card--primary {background: #409eff;}
