css样式融合与类继承
youngwind opened this issue · 1 comments
youngwind commented
前言
前一阵子用了一下css-module,有一个问题没有解决,那就是同样一个元素添加多个类名的情况。比如我想要这样的效果。这种做法很常见,一般用于.title定义公共样式,title#{n}定义各自独有的样式。
<div class="title title1"></div>
<div class="title title2"></div>
如果希望通过css-module来完成的话,代码大概是这样。
import style from "./index.scss"
<div className={style.title, style.title1}></div>
<div className={style.title, style.title2}></div>
但是会报错,因为官方的css-module只能接受一个变量字符串。
#1. 通过类名解决
当时找到了两个解决方案。
- 字符串拼接。
<div className={style.title + " " + style.title1}></div>
但是这种方法好搓啊。。。肯定有更优雅的解决方案。
2. react-css-module
这个loader可以直接定义多个类名,具体参考这里
#2. 通过样式继承解决
后来跟别人交流这个问题的时候得出以下的帮助:
官方说法,css-module在设计的时候就没打算支持多个类名,因为在他们看来,每一个元素应该像一个对象一样,只添加一个className值,至于样式的融合应该通过样式的继承来完成。
嗯,细细想来,还是很有道理的。这样每个元素最多只有一个类名,简洁多了。
scss的继承与占位符
在我用scss的继承去实现它的时候发现一个有趣的问题。
.title {
height: 100px;
}
.title1 {
@extend .title;
background-color: blue;
}
.title2 {
@extend .title;
background-color: pink;
}
scss-lint会报语法警告,如下。
查阅了一下,才发现scss的继承和占位符的细微区别。
上面的scss代码会被编译成这样子。
.title, .title1, .title2 {
height: 100px;
}
.title1 {
background-color: blue;
}
.title2 {
background-color: pink;
}
但是如果我们不需要用到.title这个类呢?如果这个类唯一存在的作用就是抽象出公共的title1和title2那一部分呢?那么,用占位符要更好。
// scss 写法
%title {
height: 100px;
}
.title1 {
@extend %title;
background-color: blue;
}
.title2 {
@extend %title;
background-color: pink;
}
编译之后是这样子的。
.title1, .title2 {
height: 100px;
}
.title1 {
background-color: blue;
}
.title2 {
background-color: pink;
}
区别在于不再有.title这个类了。
riskers commented
css-module 有 composes
应该可以解决