如何为background:url()中的SVG实现CSS:hover颜色切换?
背景SVG使用
currentColor实现hover颜色切换失效的解决方案 问题描述
我尝试为通过background:url()引入的SVG设置简单的CSS:hover颜色切换效果,使用stroke="currentColor"却无法生效。目前似乎只能通过复制SVG代码并修改颜色实现,但这并非优雅方案,请问我是否遗漏了什么?
原代码示例
.sz30 { --siz : 30px; display : inline-block; width : var(--siz); height : var(--siz); margin : 1rem; background-size : cover; cursor : pointer; caret-color : transparent; } .test_ccGreen { color:green; background : url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" stroke="currentColor"><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>'); } .test_ccBlue { color:blue; background : url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" ><defs>%3Cstyle%3Epath{stroke:currentColor;}%3C/style%3E</defs><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>'); } .test_ccGreen:hover, .test_ccBlue:hover { color:red; } .test_duplicateSVG { background : url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" stroke="rgb(24,97,52)"><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>'); } .test_duplicateSVG:hover { background : url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" stroke="crimson"><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>'); }
<div class="sz30 test_ccGreen"></div> <div class="sz30 test_ccBlue"></div> <div class="sz30 test_duplicateSVG"></div>
原因分析
当SVG作为背景图片(无论是data URI还是外部文件)引入时,它是独立的渲染上下文,无法继承宿主元素的currentColor值。宿主元素的color属性无法穿透到背景SVG内部,所以你设置的stroke="currentColor"只会取SVG自身的默认颜色(通常为黑色),不会响应宿主的hover状态变化。
可行解决方案
方案1:CSS Mask + 背景色(推荐)
不需要修改SVG结构,利用CSS mask将SVG作为遮罩,通过改变宿主元素的背景色实现hover切换:
.sz30 { --siz: 30px; display: inline-block; width: var(--siz); height: var(--siz); margin: 1rem; cursor: pointer; caret-color: transparent; /* 兼容webkit内核浏览器 */ -webkit-mask: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" stroke="black"><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>') center/cover no-repeat; mask: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" stroke="black"><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>') center/cover no-repeat; background-color: green; } .sz30:hover { background-color: red; }
方案2:内联SVG而非背景图
如果需要保留SVG内部的样式逻辑,可以将SVG直接内联到HTML中,这样它就能继承宿主元素的color值:
<div class="sz30 test-inline"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" stroke="currentColor"> <path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/> <path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/> </svg> </div>
.test-inline { color: green; } .test-inline:hover { color: red; } .test-inline svg { width: 100%; height: 100%; }
内容的提问来源于stack exchange,提问作者Mister Jojo
相关产品推荐
相关产品推荐

