深色模式下的图标怎么处理
承接搜索意图:场景
深色模式不是把颜色反过来就完事。纯黑填充会直接消失,1px 细线在深底上显得更细,彩色图标可能变得刺眼。稳妥做法是让图标颜色由主题变量驱动,而不是准备两套互不相干的资源。
本文目录
首选:currentColor + 主题变量
内联 SVG 把 fill / stroke 设为 currentColor,主题切换时只改父级 color;需要多档色阶时改用 CSS 变量。这样浅色、深色、高对比模式共用同一份文件,不会出现两套资源不同步。
:root { --icon: #3e7c46; --icon-muted: #7d8c7f }
@media (prefers-color-scheme: dark) {
:root { --icon: #9ad0a4; --icon-muted: #6f8574 }
}
.icon { color: var(--icon) } /* SVG 内用 currentColor */外部 img 引用怎么办
外部 SVG 不继承页面样式。三条路:改成内联;用 CSS mask(颜色由 background-color 给);或者准备深浅两套文件并按 prefers-color-scheme 切换。第三种最直观,但要记得两套文件保持同步。
谨慎使用 filter: invert
一行 filter: invert(1) 确实能把黑色图标变白,但彩色图标、带灰阶的插画会被反成怪色,半透明区域也会失真。只适合纯单色图标,且最好配合 hue-rotate 校正品牌色;长期项目仍建议走变量方案。
- 纯单色线性图标:可临时用 invert
- 彩色 / 双色 / 插画:另出深色版
- 别对整页统一 invert,会让图片一起反色
深色底上的对比度与线宽
图标也是信息,同样要满足可读性:次要图标不要压得太暗,关键状态不能只靠亮度区分。原本 1.5px 的线在深底上看起来会更细,可考虑深色模式单独把 stroke-width 提到 1.75 或 2,并在真机上过一遍。
主题切换的三种实现与取舍
第一种是纯 CSS 媒体查询,跟随系统设置,零脚本、最省事,用户不能在站内手动覆盖;第二种是 data-theme 属性配合站点自己的切换按钮,可控性最好,也是多数产品在用的方式;第三种是两者结合——默认跟随系统,用户手动切换后把选择存起来。三种方式对图标的要求相同:颜色不能写死在 SVG 里。切换时记得同时处理边框、分割线和图标的禁用态,只换图标颜色会让整套界面看起来像换了一半。
- 跟随系统:@media (prefers-color-scheme: dark)
- 站内切换:data-theme + CSS 变量
- 混合方案:默认跟随系统,手动选择优先
- 禁用态、分割线、边框一起跟着换
常见问题
深色模式下图标不见了?多半是 SVG 里写了固定的黑色填充,改成 currentColor 或按主题给变量。
需要为每个图标做两份文件吗?内联或 mask 方案不需要;外部 img 引用又不能用 mask 时才需要两份。
相关素材 · 12 个素材