scss + BEM
BEM 解决了什么问题
- 语义化的标签易于阅读,更优雅。
- 解决了命名冲突
- 适合组件化开发、协同开发
概念
Bem 是块(block)、元素(element)、修饰符(modifier)的简写,由 Yandex 团队提出的一种前端 CSS, 命名方法论。class名可以获得更多的描述和更加清晰的结构;使代码易于阅读理解,方便协同开发
- Block块:代表的是包裹我的容器。可理解为组件最外层元素
- Element元素:代表的是我是谁 ,组件的后代元素
- Modifier修饰符:代表的是我处于什么状态。
命名规则
- -中弧线连接单词,可以是块元素也可以是子元素
- __ 双下划线 连接块与块的子元素 (其实单下划线也是可以的,但由于命名习惯中单下划线有时候也作为单词连接符,造成混淆,所以使用双下划线更为稳妥)
- – 双中划线 描述一个块或者块的子元素的一种状态
- is is-关键字结合使用时,指示模块特定的状态类;一般用于js控制样式时,css命名用is-开头 例如 is-open、is-disabled
- 如果你想写个日历组件?
.calendar
- 如果你想在日历组件中加个按钮?
.calendar__btn
- 如果想在按钮上加个主要状态?
.calendar__btn--main
查看element-ui 中BEM 定义
/* 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;
}
}
}
解析BEM
$namespace = 'my'
//编译前
@include b(calendar) {
border-radius: 4px;
@include e(footer) {
//传入单个
padding: 20px;
}
@include m(primary) {
background: #409eff;
}
}
//编译后
.my-calendar {
border-radius: 4px;
}
.my-calendar__footer {
padding: 20px;
}
.my-calendar--primary {
background: #409eff;
}
由此可以理解BEM 是按照指定的规则去拼接元素,达到统一代码分格,简便代码的作用
如何简化scss 代码
使用&
符号简化
- 源代码
.my-calendar {
border-radius: 4px;
}
.my-calendar__footer {
padding: 20px;
}
.my-calendar--primary {
background: #409eff;
}
- 简化后的代码(
&
)
.my-calendar {
border-radius: 4px;
&__footer {
padding: 20px;
}
&--primary {
background: #409eff;
}
}
使用mixin 简化代码
需求:根据UI,大量文案每行文案都不同
- 源代码
.my-calendar__title {
font-size: 18px
font-weight: 500
color: red
line-height: 18px
}
.my-calendar__content {
font-size: 20px
font-weight: 400
color: red
line-height: 20px
}
.my-calendar__footer {
font-size: 30px
font-weight: 400
color: blue
line-height: 20px
}
- 简化后代码
@mixin fontStyle($s, $w, $c, $lh) {
font-size: $s
font-weight: $w
color: $c
line-height: $lh
}
.my-calendar__title {
@include fontStyle(18px, 500, red, 18px)
}
.my-calendar__content {
@include fontStyle(20px, 400, red, 20px)
}
.my-calendar__footer {
@include fontStyle(30px, 400, blue, 20px)
}