问题:vue页面中(样式使用less书写),软件系统定制开发对的组件使用/deep/软件系统定制开发进行样式穿透修改默认样式,发现在Google Chrome版本64软件系统定制开发上看样式修改成功,软件系统定制开发但在火狐浏览器、edge版本101、高版本谷歌浏览器中查看,发现样式穿透失效。
解决:
1.组件内scoped的样式,/deep/只写在外层父元素,父元素内部的子元素不再写/deep/
- <style scoped>
- /deep/ .ivu-form {
- ...
- .ivu-form-item{
- ...
- }
- }
- </style>
2.全局样式,不写/deep/ 。
问题是解决了,但这是为什么呢?
分析:
1.为什么要加scoped?
为了使当前的样式只作用在当前组件,若无这个限制的话,写在这个组件内的样式就可能会影响其他具有相同css选择器名称组件的样式。
2.为什么加了scoped就能只作用于组件内呢?
解释道:
<style scoped>
@media (min-width: 250px) { .list-container:hover { background: orange; } }
</style>
这个可选
scoped
attribute 会自动添加一个唯一的 attribute (比如data-v-21e5b78
) 为组件内 CSS 指定作用域,编译的时候.list-container:hover
会被编译成类似.list-container[data-v-21e5b78]:hover
查看页面,发现加了scoped的组件A作用域内的DOM节点和子组件都有了一个自定义属性:data-v-hash,再查看编译后作用于DOM节点的css选择器为 .class-name[data-v-hashA] ,而不同组件的data-v-hash的hash值不一样,所以组件内的样式只作用于本身而不会影响其他相同class(id等)名的组件。 若组件B有相同的class-name,但无scoped,则作用于组件B的css选择器为.class-name,所以组件A的样式.class-name[data-v-hashA] 也不会影响组件B。
如下:
3.为什么使用/deep/后就能样式穿透?
- <style scoped>
- /deep/ .ivu-form {
- ...
- }
- </style>
上面说到:加了scoped的组件作用域内的DOM节点和子组件都有了一个自定义属性:data-v-hash,但子组件只会在最外层会加上父组件的data-v-hash。而加了scoped的情况下,vue编译后的css样式会在我们自定义的选择器后加上[data-v-hash]选择器,但子组件内部的DOM节点并没有父组件的data-v-hash属性,所以样式未生效。
加上/deep/,是使得vue编译此处的css样式时,将[data-v-hash]选择器作为父级条件,作为子组件的DOM,上级肯定会有节点有data-v-hash属性,所以样式作用成功。
例:
F12,查看作用于这个span节点的样式,发现:不加/deep/时,对应的css样式是 .ivu-btn-warning span[data-v-hash] {...},加上/deep/后,对应css变为了 [data-v-hash] .ivu-btn-warning span {...}
4.为什么有的浏览器会样式穿透失败?
- <style scoped>
- /deep/ .ivu-form {
- /deep/.ivu-form-item{
- ...
- }
- }
- </style>
这种嵌套/deep/的写法,发现在Google Chrome版本64里能样式穿透成功,F12,查看Sources面板,发现页面编译好的样式为:
[data-v-124sd13] .ivu-form .ivu-form-item {....} ......
但在发现编译后为如下所示,所以ivu-form-item内样式未生效:
[data-v-124sd13] .ivu-form /deep/ .ivu-form-item {....} ......