使用实践
保证各个部分只有一级 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也可独立在其他地方复用
-->
<div
class="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;
}