scss mixin svg 颜色控制 以及与 png 方案对比讨论

初来时发现团队内项目对图标的使用上,已经形成了围绕 svg 的一套 设计 & code 规范:

  • 图标基本是 svg 作为组件引入项目中
  • 设计师使用 svg 的 fill 属性来控制图标颜色,方便开发使用 css 直接变换颜色

优势就是一些 hover 之类的复杂交互状态下,需要图标变色时,可以直接通过 css 控制颜色,而不是引入多张像素图,确实比较方便。 但是这种方式依然存在一些问题

  1. css 中每次需要变色时在单独处理 css fill 等属性,效率低下
  2. 一些色彩丰富的图是没有设计变色状态的,不应该被复用的交互变色 css 覆盖样式
  3. 一些颜色是通过 stroke 而不是 fill 实现,fill 反而被用作透明 filter 掉底色
  4. 复杂的非规则图形,使用 path 实现,大小上相较于 png 反而没有容量优势

基于遇到的问题,逐步探索出了一些经验以及方法

scss mixin

首先使用 scss mixin 构建了一个 快捷方法

scss 复制代码
/** 可以保持 文本颜色与 svg 颜色一致 */
@mixin colorWithSvg($color: #ffffff) {
  & {
    fill: $color;
    path {
      fill: $color;
    }
    ellipse {
      stroke: $color;
      fill: $color;
    }
  }
}

进一步解决 不需要变色的 svg 的问题 以及 只想要影响 svg 不影响文本色

问题 3 中只能规范设计,而 filter 底色的问题 css 不会覆盖 path 上的 fill-opacity ,实际使用时注意实际效果即可

因为多色图标属于少数,所以在项目中引入 svg 时手动添加一个 owner-color 属性来标记不需要被变色的 svg

html 复制代码
<svg owner-color="true" ...></svg>
scss 复制代码
/** svg 填充色 */
@mixin colorFillSvg($color: #ffffff, $svgCheckOwner: false) {
  @if $svgCheckOwner {
    &:not([owner-color]) {
      // ...
    }
  } @else {
    & {
      // ...
    }
  }
}

/** font color 与下级 svg 填充色一致 */
@mixin colorWithSvg($color: #ffffff, $svgCheckOwner: false) {
  color: $color;

  svg {
    @include colorFillSvg(currentColor, $svgCheckOwner);
  }
}

svg 压缩

svg 如果绘制了一个非常复杂的图形,那么将会失去他的体积优势,这时候就需要对 svg 进行压缩,可以参考张鑫旭 - SVG 在线压缩合并工具

当前 svg 使用时需要注意的是能使用的 安全压缩选项 是有限的,压缩后仍需要注意检查,路径精度压缩 即可压缩大部分体积

有选择地使用 svg

在实际使用中可以总结出 svg 的优点:

  • 变色方便(需要检查实际效果)
  • 无损放大
  • 体积小(简单图形,需要注意压缩路径精度)

但仍有一些缺点:

  • 复杂图形体积大,2x.png 小得多
  • 相同 svg 在一个上下文中,def 会因为当前生效 css 互相影响
  • 变色仍有一定的限制
  • document reflow/repaint 影响性能

所以 svg 图标还是一个需要花费精力处理的资源类型,不能盲目追求 svg 化

相关推荐
欧阳的棉花糖几秒前
React 小误区:派生值 vs useEffect
前端
马可菠萝3 分钟前
从零开始,用 Tauri + Vue 3 打造轻量级桌面应用
前端
陆枫Larry4 分钟前
JavaScript 字符串处理实战:从 `startsWith` 到链式 `replace` 的避坑指南
前端
天蓝色的鱼鱼21 分钟前
你的项目真的需要SSR吗?还是只是你的简历需要?
前端·架构
恋猫de小郭1 小时前
移动端开发稳了?AI 目前还无法取代客户端开发,小红书的论文告诉你数据
前端·flutter·ai编程
文心快码BaiduComate1 小时前
百度云与光本位签署战略合作:用AI Agent 重构芯片研发流程
前端·人工智能·架构
闲云一鹤2 小时前
nginx 快速入门教程 - 写给前端的你
前端·nginx·前端工程化
QCY2 小时前
「完全理解」1 分钟实现自己的 Coding Agent
前端·agent·claude
一拳不是超人3 小时前
Electron主窗口弹框被WebContentView遮挡?独立WebContentView弹框方案详解!
前端·javascript·electron
anyup3 小时前
🔥2026最推荐的跨平台方案:H5/小程序/App/鸿蒙,一套代码搞定
前端·uni-app·harmonyos