欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

CSS 技巧 | 如何更改 svg 的颜色

最编程 2024-03-25 08:18:05
...

场景描述

当鼠标移到卡片上,svg 格式的 icon 颜色可以变化

ainimation.gif 这个需求实现方式有很多,最基本的可以通过监听鼠标移入/移出事件,准备两套图片,根据状态切换:

import React, { useState } from 'react';

const [imgSrc,setImgSrc] = useState();

var example = document.getElementById("example");
example.addEventListener("mouseover", function(){
    console.log("鼠标移入了元素");
    setImgSrc(iconLight) // 更新图片src为亮色图
});
example.addEventListener("mouseout", function(){
    console.log("鼠标移出了元素");
    setImgSrc(iconDark) // 更新图片src为暗色图
});

但挺麻烦,如果容器中每个item的图片都不一样,那图片一共要准备 2N 张,以及大量的状态切换会让代码脏乱。

进阶偷懒

我不想整这么多图,也不想搞这么多状态!

能不能直接给 icon 改个色直接用就行呢?

可以,用.SVG格式图片(因为我写的是个内部工具小需求,*度比较高,以下描述的方法仅适合纯色icon)

前置准备

截屏2023-11-07 14.08.55.png

由于是小需求,所以 icon 也没设计同事出,所以直接去开源的网站拿。

我用的是 iconfont 接下来的例子用到的资源都这里找的。

进入 icon 图标库,随便点一个,发现有多种方式获取icon资源。接下来有两种解法可以实现:

截屏2023-11-07 14.10.25.png

方法一:引入 svg 代码,修改 fill 颜色

点击复制 SVG 代码,会得到如下内容:

<svg
  t="1699337638484"
  class="icon" // 我用的 JSX 所以一会要改用className
  viewBox="0 0 1024 1024"
  version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  p-id="1322"
  width="16"
  height="16">
  <path
    d="M373.08 481.35q-28.51 2.28-57.12 2.28t-57.46-2.28a96.2 96.2 0 0 1-88.24-88.24q-2.26-28.6-2.26-57.29t2.29-57.3a96.2 96.2 0 0 1 88.24-88.23q28.56-2.29 57.26-2.29t57.29 2.29a96.2 96.2 0 0 1 88.24 88.23q2.28 28.61 2.29 57.3t-2.29 57.29a96.2 96.2 0 0 1-88.24 88.24zM628.1 480.83q-22-18.76-42.47-39.21t-39.45-42.72a97.26 97.26 0 0 1 0-126.17q18.81-22.08 39.33-42.59t42.59-39.33a97.26 97.26 0 0 1 126.17 0q22.08 18.81 42.6 39.33t39.32 42.59a97.26 97.26 0 0 1 0 126.17q-18.81 22.1-39.32 42.6t-42.6 39.33a97.28 97.28 0 0 1-126.17 0zM373.08 856.74Q344.57 859 316 859t-57.46-2.29a96.2 96.2 0 0 1-88.24-88.23q-2.28-28.6-2.29-57.3t2.29-57.29a96.2 96.2 0 0 1 88.24-88.24q28.59-2.28 57.29-2.28t57.29 2.28a96.2 96.2 0 0 1 88.24 88.24q2.28 28.61 2.29 57.29t-2.29 57.3a96.2 96.2 0 0 1-88.28 88.26zM748.48 856.74Q720 859 691.36 859t-57.47-2.29a96.2 96.2 0 0 1-88.23-88.23q-2.29-28.6-2.29-57.3t2.29-57.29a96.2 96.2 0 0 1 88.23-88.24q28.61-2.28 57.3-2.28t57.29 2.28a96.21 96.21 0 0 1 88.24 88.24q2.28 28.64 2.28 57.32t-2.28 57.3a96.21 96.21 0 0 1-88.24 88.23z"
    p-id="1323"
    fill="#2c2c2c"></path>
</svg>

可以看到 path 标签里有一个属性叫 fill ,这个值决定了 icon 的颜色。

如果用网站自带的颜色选择器,选了颜色后再复制 SVG 代码就会得到带 fill 属性的内容。

但这个内联属性(优先级高)覆盖了我们通过 className 赋予的颜色样式。

所以要删掉,然后用 css 伪类 :hover 实现颜色变化。

<svg
  t="1699337638484"
  className="logo"
  viewBox="0 0 1024 1024"
  version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  p-id="1322"
  width="16"
  height="16">
  <path
    d="M373.08 481.35q-28.51 2.28-57.12 2.28t-57.46-2.28a96.2 96.2 0 0 1-88.24-88.24q-2.26-28.6-2.26-57.29t2.29-57.3a96.2 96.2 0 0 1 88.24-88.23q28.56-2.29 57.26-2.29t57.29 2.29a96.2 96.2 0 0 1 88.24 88.23q2.28 28.61 2.29 57.3t-2.29 57.29a96.2 96.2 0 0 1-88.24 88.24zM628.1 480.83q-22-18.76-42.47-39.21t-39.45-42.72a97.26 97.26 0 0 1 0-126.17q18.81-22.08 39.33-42.59t42.59-39.33a97.26 97.26 0 0 1 126.17 0q22.08 18.81 42.6 39.33t39.32 42.59a97.26 97.26 0 0 1 0 126.17q-18.81 22.1-39.32 42.6t-42.6 39.33a97.28 97.28 0 0 1-126.17 0zM373.08 856.74Q344.57 859 316 859t-57.46-2.29a96.2 96.2 0 0 1-88.24-88.23q-2.28-28.6-2.29-57.3t2.29-57.29a96.2 96.2 0 0 1 88.24-88.24q28.59-2.28 57.29-2.28t57.29 2.28a96.2 96.2 0 0 1 88.24 88.24q2.28 28.61 2.29 57.29t-2.29 57.3a96.2 96.2 0 0 1-88.28 88.26zM748.48 856.74Q720 859 691.36 859t-57.47-2.29a96.2 96.2 0 0 1-88.23-88.23q-2.29-28.6-2.29-57.3t2.29-57.29a96.2 96.2 0 0 1 88.23-88.24q28.61-2.28 57.3-2.28t57.29 2.28a96.21 96.21 0 0 1 88.24 88.24q2.28 28.64 2.28 57.32t-2.28 57.3a96.21 96.21 0 0 1-88.24 88.23z"
    p-id="1323"></path>
</svg>
.logo {
  width: 30px;
  height: 30px;
  fill: #249ffd;
}

.logo:hover {
  width: 30px;
  height: 30px;
  fill: #ffffff;
}

方法二:引入 svg 图片,修改 drop-shadow

方法一会导致代码里出现大量的 svg 标签,又会导致代码脏乱。能更简单一点吗?

可以,不过要用奇技淫巧:CSS3 滤镜 filter 中的 drop-shadow https://developer.mozilla.org/zh-CN/docs/Web/CSS/filter-function/drop-shadow

截屏2023-11-07 14.38.07.png 下载svg图片到本地,然后 import 引入。通过 filter: drop-shadow 修改投影颜色改变 icon 颜色

import logo from './logo.svg';

<img
  className="logo"
  style={{ transform: 'translate(-100px)' }}
  src={logo}
/>
.item {
  overflow: hidden;  // 超出父级范围裁掉,隐藏投影
}
.logo {
  width: 30px;
  height: 30px;
  filter: drop-shadow(100px 0 0 #249ffd);
}

.logo:hover {
  width: 30px;
  height: 30px;
  filter: drop-shadow(100px 0 0 #ffffff);
}

为什么说是奇技淫巧呢?归根到底还是兼容性的问题,需要根据你的具体业务,合理使用技巧。

截屏2023-11-07 14.46.56.png

参考文档

  1. PNG格式小图标的CSS任意颜色赋色技术:www.zhangxinxu.com/wordpress/2…

  2. CSS3 filter:drop-shadow滤镜与box-shadow区别应用:www.zhangxinxu.com/wordpress/2…

  3. img标签使用svg改变颜色:lhalcyon.com/change-svg-…