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 化

相关推荐
雨季66617 小时前
构建 OpenHarmony 简易文字行数统计器:用字符串分割实现纯文本结构感知
开发语言·前端·javascript·flutter·ui·dart
小北方城市网17 小时前
Redis 分布式锁高可用实现:从原理到生产级落地
java·前端·javascript·spring boot·redis·分布式·wpf
console.log('npc')17 小时前
vue2 使用高德接口查询天气
前端·vue.js
2401_8920005217 小时前
Flutter for OpenHarmony 猫咪管家App实战 - 添加支出实现
前端·javascript·flutter
天马379817 小时前
Canvas 倾斜矩形绘制波浪效果
开发语言·前端·javascript
天天向上102418 小时前
vue3 实现el-table 部分行不让勾选
前端·javascript·vue.js
qx0918 小时前
esm模块与commonjs模块相互调用的方法
开发语言·前端·javascript
Mr Xu_19 小时前
前端实战:基于Element Plus的CustomTable表格组件封装与应用
前端·javascript·vue.js·elementui
0思必得019 小时前
[Web自动化] 爬虫之API请求
前端·爬虫·python·selenium·自动化
混迹在开发队伍里的伪开发19 小时前
css的var用法,定义属性,全局使用
前端·css