如何避免CSS filter:invert修改div元素的::selection选中样式
问题根源
CSS 中 filter 属性会作用于整个元素的渲染上下文,包含元素内部的所有文本、子元素、伪元素,无法单独指定某个伪元素跳过父元素的 filter 效果。之前的写法失效有两个核心原因:
- 给
.a::selection加filter: invert(1)相当于在父级反转的基础上再反转一次,最终效果等于没有反转,达不到需求 :not(::selection)属于非法写法,CSS 规范不允许将伪元素作为:not的参数
可行解决方案
方案1:无需修改DOM,直接适配选中态色值
适合不能调整HTML结构的场景,因为父级已经加了 invert(1) 反转效果,只需要给 .a::selection 设置和全局选中态相反的色值,经过父级反转后就会得到预期的和全局一致的选中效果,修改后的CSS代码如下:
*::selection { background: #000; color: #fff; } .a, .b { background: red; color: yellow; } .a { filter: invert(1); } /* 新增这段即可 */ .a::selection { background: #fff; color: #000; }
方案2:调整DOM结构,从根源避免filter影响选中态
如果可以调整HTML结构更推荐这个方案,不需要手动换算色值,后续修改全局选中样式也不需要同步调整。
首先修改HTML,给.a内部的文本加一层包裹:
<div class='a'> <span class="a-inner"> The amount of the conversion, specified as a number or a percentage. A value of 100% is completely inverted, while a value of 0% leaves the input unchanged. Values between 0% and 100% are linear multipliers on the effect. The lacuna value for interpolation is 0. </span> </div> <br/> <div class='b'> The amount of the conversion, specified as a number or a percentage. A value of 100% is completely inverted, while a value of 0% leaves the input unchanged. Values between 0% and 100% are linear multipliers on the effect. The lacuna value for interpolation is 0. </div>
再调整CSS,把filter加给内层元素,外层的选中态不受影响:
*::selection { background: #000; color: #fff; } .a, .b { background: red; color: yellow; } /* filter仅作用于内层文本包裹元素 */ .a .a-inner { filter: invert(1); }
内容的提问来源于stack exchange,提问作者Karuppiah RK
相关产品推荐
相关产品推荐

