目前BU CSS类名的写法并没有统一。
我这里用的是后代+子类选择器的写法,仍然可能产生样式冲突,特别是对.title之类的通用含义的元素。
有一些同事是用的改编的BEM。
另一两个同事用的CSS-IN-JS。
写这篇文章的目的在于比对BU以及市面上一些主流写法的理念、原理、区别与优劣,最终选择一种能解决大部分问题的写法,在BU内推广达成统一。
接下来会沿着这几个发面逐渐展开:
1.写法比较
2.一些明星产品的写法
3.pick出最倾向的写法,深入展开
4.如何推进替换
今天先写不同写法之间的比较。
写法比较
后代选择器式
.biz-a-component .container{
background: red;
}
会存在如下问题:
1.如果a组件是b组件的子组件(包裹在b里面),那么a的样式会被污染
// a组件
.biz-a-component .container{
background: red;
}
// b组件
.biz-b-component .container{
background: black;
}
2.如果一个组件比较复杂,有很多子组件,那么在子组件里面,都需要加上前缀,否则容易样式冲突
// √
.biz-main-component .child-component-a{
color: red;
}
// × ,这样更容易冲突
.child-component-a{
color: red;
}
子选择器式
.biz-a-component > .container{
background: red;
}
可以解决后代选择器的问题1。不过这种写法缺乏灵活性,当结构变动后,样式可能失效:
// 改前
xxx
// 改后
xxx
通常我们业务中可能会去覆盖组件的样式,这意味着之前覆盖的样式由于组件结构的改变,也可能失效。
BEM
BEM即 Block、Element、Modifier。
举个例子,下面form
是block,form__input
是element,form__submit--disabled
是modifier。
而写css的时候不做嵌套,都独立写,这样的好处就是结构发生变化的时候,样式不需要跟着调整。
.form {
}
.form--theme-xmas {
}
.form--simple {
}
.form__input {
}
.form__submit {
}
.form__submit--disabled {
}
这里面有个值得思考的问题,就是如果结构层级比较深,是否需要把层级在类里面展示出来?比如下面结构:
如果我们要在类名上展示结构,那类名就得这样写:
.tabbar__item__icon {}
.tabbar__item__badge {}
当组件足够复杂的时候,写起来就非常难受了。
而且还会有个问题,当结构发生变化时,类名也得跟着变,比如badge变到了icon里面,那么需要去改写:
.tabbar__item__icon__badge {}
那如果类名上不展示结构呢?元素少一些还好,一旦组件复杂起来,很可能有几十个子组件,你得给每个组件命不同的名字,即使都是标题,或者wrapper。
而且不展示结构,你光看css看不出结构,样式改起来就会很麻烦,得对照html的结构去改,所以我个人觉得这种写法非常不可取。
我们BU的类BEM式
// 完全的
常见问题:
...
// 不完全的,比如title还是简写
质检(
{size}
码)
.page-order-quality {
height: 100%;
&-content {
display: flex;
height: 100%;
}
&-cascader-wrapper {
width: calc(100% - 336px);
background: $color-line1-1;
height: 100%;
}
&-operation-wrapper {
padding: 0 55px;
width: 336px;
background: $color-white;
}
...
}
跟BEM类似,类名展示了结构,跟BEM存在同样的问题,并且有点不伦不类,没有明确地标识出block、element、modifer的区分。
改进的地方在于结合js简化了前缀的写法。
本篇介绍了 后代选择器式、子类选择器式、BEM、类BEM式。没有一个完美的,都或多或少存在问题。
接下来会继续比较其它更前沿、高级的方案。
[r2 day 11]