问题:vue页面中(样式使用less书写),对iview的组件使用/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就能只作用于组件内呢?

Vue.js官网解释道:

<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 {....}  ......

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐