详解Vue中的样式穿透>>>
如果想在一个组件中覆盖插件的样式,就需要用到样式穿透。发现问题:组件无法覆盖插件的样式如下所示,下面是一个分页器插件,默认的颜色是蓝色,定义在.swiper-pagination-bullet-active中。如果想要覆盖插件默认的样式,在组件中直接设置样式是不会生效的。这是因为组件自己的样式出现在前面,而插件的样式会从后面进来。如图所示,可以看到head标签中有多个style,组件样式定义在最上
以下内容来源:哈默聊前端
https://www.bilibili.com/video/BV1Jv41117QN
如果想在一个组件中覆盖插件的样式,就需要用到样式穿透。
发现问题:组件无法覆盖插件的样式
如下所示,下面是一个分页器插件,默认的颜色是蓝色,定义在.swiper-pagination-bullet-active
中。
如果想要覆盖插件默认的样式,在组件中直接设置样式是不会生效的。
这是因为组件自己的样式出现在前面,而插件的样式会从后面进来。如图所示,可以看到head标签中有多个style,组件样式定义在最上面,而插件的样式在下面。由于两处地方都设置了同一个属性,后面设置的属性优先级更高,因此插件的样式胜出,颜色仍然是蓝色,组件中覆盖没有生效。
style中scoped的原理
如果想要组件中的样式只针对当前组件生效,就需要在style标签中加一个scoped。它会给组件根元素的div加上一个data-v-xxx的属性。
然后组件里面所有的样式都被加上了这个属性,使得样式只作用于当前组件中的.wrapper
。如果一个页面中有很多组件,并且都有.wrapper
选择器的话,不同组件的data-v-xxx属性肯定是不一样的,所以加了scoped就可以实现只作用于当前组件的效果。
使用样式穿透设置插件样式
在组件中设置插件的样式,就需要用到样式穿透,也就是>>>
,这实际上也是利用CSS中优先级的原理。
可以看到使用了样式穿透之后,就会比原来插件的样式多一个选择器,因此优先级更高,所以设置的橙色就生效了。
注意:使用样式穿透的前提是在style标签中加scoped,如果没加scoped则不会生效。
不使用样式穿透覆盖插件样式
根据上面的分析已经可以看出,如果想要在组件中覆盖插件的样式,只需要保证组件中的选择器的优先级比插件中选择器高就行。如下所示,style中没有加scoped,选择器上也没有加样式穿透,但是组件中比插件多了一级选择器,橙色也会生效。但这样会有一个问题,.swiper-pagination-bullet-active
这个选择器就会来源不明,当前组件中没有这个类名。这样写的话就会给同事挖坑,给同事造成困扰。所以加上scpoed和>>>很容易就能明白这个选择器来源于插件内部。
其实scoped的CSS是允许修改根元素的样式的。如下图所示,在组件中其实也是不存在.swiper-container
这个类名的,但是这样设置的height: 100%
是可以生效的。
可以看到.swiper-container
其实是wrapper
下面的根元素,因此可以在scoped的CSS中设置样式。但是.swiper-pagination-bullet-active
比.swiper-container
层级更深,并且也不是根元素,所以不能直接这样设置样式,需要使用样式穿透。
写在最后
注意,有些css预处理器,比如Sass, Less,可能无法正确解析>>>,这种情况下,可以使用/deep/或::v-deep代替
“这些深度选择器的写法最终都会被编译掉的,所以和浏览器兼容性无关。” 上面是尤大的原话,可以参考一下~
更多推荐
所有评论(0)