前言
经常我们的项目中会使用大量的库,大量的库并存就产生了一个问题,就是冲突、覆盖的问题。其中JS库的冲突问题还不突出,因为一个负责任的JS库都会解决潜在的冲突问题。但是CSS库就不一定了,尤其是一些UI框架,它们往往追求用最少的CSS选择器来管理最多的标签,比如直接就给input
标签reset了样式,然后你再引入其他库的时候就很可能会破坏其他库的样式,导致页面烂掉。最关键的是CSS并没有作用域的概念,所以冲突很容易发生。
解决思路
比如,某个库,它的代码有:input {width: 100%;}
,这么屌!这么简单就把所有的input全设成了百分百宽度,霸气!然而其他的库就倒了霉了。怎么办?
我的做法是:
1、找出不负责任的CSS库,可能不止一个,但最好只有一个,因为没必要用太多不负责任的库。
2、优先引入将这个库,这样它就不会覆盖后面的更严谨的库。
3、如果它依然影响了其他的库,怎么办,这就是我们今天要讨论的问题,我的做法是给这个库加个“作用域”,当然CSS是没有作用域的,但是可以给祖先元素设置类,变相实现作用域。现在我改成.xxlib input{width: 100%}
,也就是只有祖先元素是.xxlib
的input,宽度才是100%。
4、如果给祖先元素加了类之后,更严谨的库依然覆盖了现在的库,那么其实我们就应该考虑一下“更严谨”的库是不是真的更严谨了。
5、假如必须解决更严谨的库覆盖现在的库的问题,可以把.xxlib input{width: 100%}
的.xxlib
改成#xxlib
,这样它的优先级更高,一般来讲就不会有问题了。但是尽量不要用这种做法,因为实践中你可能要写很多个<div id="xxlib"></div>,这在语义上是不允许的。
操作
先引入一个库谁都会,但是怎么修改这个库,加祖先类呢?这就是个问题了。
我的做法是,用SASS工具。
假设一:该库提供了scss源文件
这时候,通常你能找到一个主文件,也就是这样的文件:
@import './themes/default/theme';
...
...
我把它改成:
.xxlib {
@import './themes/default/theme';
...
...
}
也就是说把它用.xxlib {}
包裹起来,然后用gulp等工具重新生成css文件,这时候,每一个选择器都会以.xxlib
开头,等于限定了作用域。
假设二:该库没有提供scss源文件
这时候就去找用于分发的文件,比如xxlib.css,甚至可以找xxlib.min.css都是可以的。
然后,将所有代码用.xxlib {}
包裹起来,然后另存为.scss文件,然后用gulp等工具重新生成css文件,效果跟假设一是一样的。
到此,我们就用最简单的方法制作了一个不跟其他库冲突的库。用的时候记得把祖先元素设上.xxlib
的类。
谢谢观看。