简介:面向需要绘制云架构图、制作技术幻灯片或设计前端页面的开发人员与架构师,这份SVG格式的图标集合围绕Azure和Microsoft体系,同时收录其他品牌标识与抽象通用图形,可应用于公有云方案演示、内部技术分享、前端界面原型等场景,省去自行搜图的成本。压缩包为zip格式,整体大小约2.57MB,内含大量以SVG为主的矢量图标文件;这些文件已经过清理和优化,并启用removeDimensions插件去除冗余尺寸定义,在深浅色背景下都可较方便地调整颜色与大小。目前已有219人学习该资源。素材整合了多套Azure主题图标,不同来源之间既有重叠也有各自独特的符号,统一收编后便于对照挑选;作者声明不拥有这些图标的所有权,内容抓取自公共互联网及Microsoft相关站点,仅作合理使用下的整理,适合个人项目、教学演示或非商业场景中快速选用,也适合需要统一视觉风格的团队按需筛选。
1. 为什么我需要一套 Azure 和 Microsoft 的 SVG 图标集合
做内部云资源管理面板的时候,最让我难受的往往不是接口联调,而是图标。Azure 服务列表要放虚拟机、存储、数据库的标识,Microsoft 产品入口又得跟 Teams、OneDrive 这些风格对齐,网上临时找的 PNG 图标要么背景色不统一,要么放大就发虚。整理一份 Azure 和 Microsoft 的 SVG 图标集合,把官方分散的图标统一收进一套目录,是我在好几个后台项目里重复做过好几遍的事。
这类集合解决的是两件事:视觉上,让云服务、产品入口、开发工具拥有同一套设计语言;工程上,按需引用、可校验、可批量处理,而不是从网页右键保存一张位图回来。适合正在搭管理台、企业门户、开发者工具,或者想把图标资产固化进设计系统的前端工程师。你看完应该能直接照着把图标接进自己的工程,也知道哪些环节最容易翻车。
2. 这套图标集合到底是什么:服务图标、产品图标与格式选型
在动手接进工程之前,先得搞清楚这类集合里装的是什么。我见过不少开发者拿到压缩包就直接全量复制进项目,结果目录里混着三类性质完全不同的文件,后面处理样式时才发现麻烦。按我的习惯,图标会按用途分成三类,处理规则也不一样。
2.1 集合里装的是什么:云服务、产品图标、品牌标识三类
第一类是云资源和服务的标识。比如虚拟机、存储账户、数据库、虚拟网络、容器、密钥保管库、监控告警这类,它们的作用是在资源列表、创建向导和拓扑图里帮用户快速辨认“这是什么资源”。这类图标的特征是基于品牌色的单色或双色造型,通常以 Azure 官方品牌色为主,视觉风格统一但每枚颜色相对固定。
第二类是跨平台产品图标,包括办公协作、开发工具、终端类应用。这一类更接近普通 UI 图标的使用方式,通常以 24px 为基准网格,提供单色版本,适合放在导航、工具栏、快捷入口这些需要和界面风格融合的位置。第三类是品牌标识,也就是正式的商标图形,使用约束最严格,颜色、比例、留白都不能随意改动。
我一般会把这类集合按 services / products / brands 三个目录归档。如果你只做云资源管理,第一类和第二类可以合并;但 brands 目录建议永远单独放,否则总有后来的人会误把它当普通图标改色。这份分类习惯在后续做批量脚本、做品牌合规检查时能省下大量沟通成本。
2.2 为什么是 SVG:可缩放、文本化、样式可编程
选择 SVG 而不是位图,第一理由是缩放。PNG 要适配不同屏幕密度通常得备 1x、2x、3x 三套文件,而 SVG 是矢量描述,容器多大就渲染多大。在管理台里同一个图标会出现在 16px 的树形列表、32px 的卡片和 64px 的空状态页面,一套 SVG 就能覆盖全部,维护成本低很多。
第二理由是 SVG 本质是 XML 文本。这意味着它可以进 Git 做 diff,可以做代码审查,可以写脚本批量检查属性。你会发现“图标变了”在评审里只是一个文本差异,而不是重新导出一张图。第三理由是样式可编程:单色图标内部如果用的是 fill="currentColor",那么在 CSS 里改一行 color 就能让图标跟随主题变化。这一点位图做不到,图标字体做起来也远不如 SVG 直接。
也有一点边界要说明:SVG 并不总是比 PNG 小。一些包含大量曲线细节的复杂图形,SVG 文件体积可能超过同等视觉尺寸的 PNG。但对管理台这类界面图标来说,图形通常简洁,SVG 配合 gzip 压缩后体积完全可控。图标字体在这里的真正短板不是体积,而是多色支持和可访问性,所以我的选择标准很简单:界面图形用 SVG,照片和复杂插画用位图。
2.3 别把 SVG 当万能:和图标字体、位图的边界
图标字体(iconfont)在老旧项目里很常见,它用字符编码映射图标,省请求、按字号缩放。但它有两个明显的痛点:一是多色图标和渐变色支持很差,品牌类标识放进去基本不能用;二是内容可访问性弱,读屏软件会把图标当作文本朗读,行为不可控。如果是新建项目且没有历史兼容负担,我不建议再引入图标字体。
PNG 的适用场景则是照片级内容、复杂插画、以及必须保证所有环境一致渲染的场合。SVG 依赖浏览器渲染,极端古老的运行环境可能会有兼容问题。至于这套集合本身,常见的做法是把官方渠道发布的图标文件原样归档,保持文件结构不变,只做目录整理和命名规范,不去改写图形内部。这样后续官方更新时,你可以直接用 diff 对比差异,而不是在一份被手工改过的副本上头疼。
3. 把图标接进工程:三种引入方式与最小可运行配置
拿到图标集合后,第一步不是写组件,而是决定以什么形态进入工程。我实践下来有三种可靠方式,分别对应原型期、中型项目、以及请求数敏感的大型应用。三种方式可以共存,但你要知道每种方式的边界。
3.1 方式一:按需复制单文件,原型和小组件最快
最直接的做法,是从集合的归档目录里挑出需要的文件,复制到项目自己的目录下。比如我处理一个验证概念的页面时,通常只复制几个图标:
mkdir -p src/assets/icons cp ~/downloads/icon-set/services/azure-vm.svg src/assets/icons/ cp ~/downloads/icon-set/products/ms-teams.svg src/assets/icons/这样做的理由很简单:原型阶段图标清单还没稳定,提前建全套图标系统是过度设计。复制单个文件后,使用方式有两种,取舍刚好相反。内联是把 SVG 内容直接写进页面,颜色能被外部 CSS 控制,但不享受浏览器缓存;外链则是用 img 标签引用,能缓存,却无法通过 CSS 改内部颜色。
<!-- 内联:CSS 可控制颜色,适合会被主题驱动的图标 --> <svg viewBox="0 0 24 24" aria-hidden="true"> <path d="...图标路径..."></path> </svg> <!-- 外链:可缓存,适合颜色固定的装饰性图标 --> <img src="/assets/icons/azure-vm.svg" alt="虚拟机" />第一个代码块里 path 的内容是从 SVG 原文件复制出来的。内联方式的关键参数是 viewBox,它决定了坐标系;如果没有 viewBox,浏览器无法正确缩放。第二个代码块的 alt 文本不是摆设,资源列表场景里借助读屏的用户需要它来表达含义。
3.2 方式二:本地图标目录加前端组件,中大型工程的常规做法
当图标数量超过二十枚,或者多个页面都在引用时,再靠复制粘贴就不合适了。常见做法是把整套集合放进项目静态目录,然后通过一个统一组件来引用。我会先把目录结构固定下来:
assets/icons/ services/ azure-vm.svg azure-storage.svg azure-database.svg products/ ms-teams.svg ms-onedrive.svg brands/ microsoft-logo.svg目录结构本身是给构建脚本用的约定,services、products、brands 三个子目录分别对应前面说的三类图标。接下来用一个组件封装引用逻辑,这里我给出一个 React 写法,换成 Vue、小程序思路都一样:
// Icon.jsx import React from 'react'; export default function Icon({ name, size = 20, className = '' }) { return ( <svg width={size} height={size} className={`ui-icon ${className}`} aria-hidden="true" > <use href={`#${name}`}></use> </svg> ); }这个组件的核心是<use href="#name">,它引用页面中已存在的 symbol 节点。name 对应构建脚本生成的 symbol id,size 控制渲染尺寸,className 让外部可以覆盖布局样式。注意这里没有 fill 属性,颜色完全交给 CSS 控制。
组件本身不会加载 SVG 文件,它是配合下一节的 Sprite 构建用的。如果你不想引入 Sprite,而是希望组件直接读取文件路径,那需要打包器的能力,或者写成<img src={...}>,但这会失去改色能力。所以我的建议是:组件引用 id 的方式最通用,也能保持颜色可定制。
3.3 方式三:合成为 SVG Sprite,控制请求数和交付体积
一个页面几十个图标,如果每个都是独立请求,网络开销不可忽略。SVG Sprite 把所有图标合并进一个文件,页面里统一引用,这是目前最成熟的方案。我会用下面这个 Node 脚本生成 Sprite,先把它放在 scripts 目录:
// scripts/build-sprite.mjs import { readdir, readFile, writeFile } from 'node:fs/promises'; import path from 'node:path'; const ICON_DIR = 'assets/icons'; const OUT_FILE = 'assets/icons/sprite.svg'; const files = (await readdir(ICON_DIR)).filter((f) => f.endsWith('.svg')); const symbols = await Promise.all( files.map(async (file) => { const raw = await readFile(path.join(ICON_DIR, file), 'utf8'); const id = file.replace('.svg', ''); // 文件名直接作为 symbol 的 id const viewBox = raw.match(/viewBox="([^"]+)"/)?.[1] ?? '0 0 24 24'; const body = raw .replace(/<\?xml[\s\S]*?\?>/g, '') .replace(/<!--[\s\S]*?-->/g, '') .replace(/<svg[^>]*>/g, '') .replace(/<\/svg>/g, ''); return `<symbol id="${id}" viewBox="${viewBox}">${body}</symbol>`; }) ); const sprite = `<svg xmlns="http://www.w3.org/2000/svg" style="display:none">${symbols.join('\n')}</svg>`; await writeFile(OUT_FILE, sprite); console.log(`生成 ${symbols.length} 个图标 → ${OUT_FILE}`);这个脚本的逻辑是:读取目录下所有 SVG 文件,用文件名作为 symbol 的 id,提取每个文件的 viewBox 属性,剥离 XML 声明和注释,把内部路径放进 symbol 节点,最后合并成一个 sprite.svg。参数 ICON_DIR 和 OUT_FILE 可以根据你的工程结构调整。
生成后,在页面入口或布局组件里引入一次 sprite 文件,然后任意位置用<use href="#id">引用:
<!-- 先引入 sprite --> <div dangerouslySetInnerHTML={{ __html: spriteContent }} /> <!-- 使用:href 指向 symbol id --> <svg class="ui-icon" aria-hidden="true"> <use href="#azure-vm"></use> </svg>注意 href 对大小写敏感,symbol 的 id 是 azure-vm 就必须写 azure-vm。如果目标环境包含老版本浏览器,可以同时保留 xlink:href 作为兼容写法。这一步做完,工程接入基本完成,剩下的是样式和尺寸的细节。
4. 样式统一:尺寸、颜色和暗色模式的三个必调参数
图标接进去以后,最常见的现象是“能显示但很乱”:有的偏大、有的偏小、有的颜色刺眼、暗色模式下一片漆黑。这些不是图标文件的问题,而是缺少统一的样式参数。接下来的三个参数,每次接入我都会逐个过一遍。
4.1 先校准尺寸:viewBox、基准网格与常见误区
一套集合里往往混着不同基准网格:有的图标 viewBox 是 0 0 24 24,有的可能是 0 0 48 48。如果你给它们设置同样的 CSS 尺寸,视觉大小会明显不一致,这是图标体感“不整齐”的第一来源。
我的做法是建立尺寸规范,用统一的组件层控制,不在业务代码里直接写死尺寸:
| 使用场景 | 推荐尺寸(px) | 说明 | | 行内文字、按钮、表格操作 | 16 | 与文字基线对齐,避免撑高行高 | | 侧边导航、工具栏 | 20-24 | 视觉重心稳定,点击区域友好 | | 卡片头部、资源类型标识 | 32 | 与标题并排时比例协调 | | 空状态、异常页提示 | 48-64 | 单独展示,信息层级清晰 |
这里有一个需要克制的地方:不要为了统一而直接改写 SVG 文件里的 viewBox。viewBox 是图形设计时的坐标系,改了会导致图形被裁切或增加大量留白。正确的做法是让组件在渲染时接收 size 参数,按尺寸规范输出 width 和 height,图形本身保持原样。我一般会把 16、20、24、32、48 做成常量,杜绝业务里出现 18、22 这类自由尺寸。
4.2 颜色策略:从 fill 到 currentColor
单色图标的颜色由 fill 属性决定。官方集合里通常有两种形态:一种内部 fill 固定为颜色值,另一种画成黑色然后交给外部控制。第二种更适合工程化,因为它配合 currentColor 可以直接继承 CSS 的 color 值。
先给所有单色图标一个基础样式:
.ui-icon { width: 1em; height: 1em; fill: currentColor; vertical-align: -0.125em; }这里使用 em 作为单位,好处是图标会跟随字体大小缩放:在 16px 标题里自然显示 16px,在 20px 按钮里显示 20px。vertical-align 调整图标与文字基线的对齐,-0.125em 是一个在多数平台上观感稳定经验值。
需要说明的是彩色品牌图标不要套用这个规则。Azure 资源标识里的品牌色是故意写死的,改掉会破坏视觉识别。常见品牌色如 Azure 主色 #0078D4、微软四色中的红色 #F25022 等,这些值以你下载的图标文件内部 fill 为准,我一般会把这些图标过滤出来,保持原样输出,只对单色图标做 currentColor 处理。
4.3 暗色模式与品牌色边界
暗色模式下,单色图标需要从深色换成浅色,这就是 currentColor 策略发挥作用的地方。利用 CSS 变量就能实现一套代码适配两种主题:
:root { --icon-color: #1a1a1a; } [data-theme='dark'] { --icon-color: #e6e6e6; } .ui-icon { fill: var(--icon-color, currentColor); }这样切换主题时,所有单色图标自动跟随。彩色品牌图标在暗色模式下没有统一答案:深蓝、深红这种颜色在深色背景上对比度会下降,但品牌图标不宜擅自调亮。我见过一些项目很聪明,给品牌图标准备了 white 变体,在深色背景上使用原图加白色底衬,或者干脆保留原样。你可以在图标集合里找找有没有提供纯色或反白版本,如果有,暗色模式就用那套;如果没有,我的建议是保持原样,不要手工调色。
5. 避坑:图标显示异常与品牌误用的排查清单
接入过程中真正耗时的不是写配置,而是排障。这一章把我反复踩过的坑按“现象、原因、解决”整理出来,每一条都对应一个真实发生过的场景,你可以直接拿来做排查手册。
5.1 图标渲染为空白或显示成纯黑文本
现象:页面上应该显示图标的位置出现一个空白方块,有时是一串乱码或黑色文本。最常见的是刚把图标接入管理系统时就出现,单个文件用浏览器打开却正常。
原因有三个层面。第一,SVG 文件本身不完整,缺少</svg>结束标签,浏览器解析到一半就丢弃了。第二,viewBox 缺失,文件虽然能渲染但无法正确缩放。第三,服务器把这枚.svg文件当作普通文本返回了,响应头里的 Content-Type 是 text/html 而不是 image/svg+xml,浏览器就不会按图形渲染。
解决:先用浏览器直接打开文件确认图形本身没问题;再看代码里是否缺结束标签;最后查服务器配置。前端开发环境最常见的是第三种,尤其在本地静态服务器上,需要强制声明 MIME 类型:
server { location ~* \.svg$ { default_type image/svg+xml; } }这段配置写在 nginx 的 server 块里,表示凡是 URL 以 .svg 结尾的请求,统一返回 image/svg+xml。如果你用的是其它静态服务器,找到 MIME 配置表补上同样的映射即可。
5.2 颜色不随主题切换,暗色模式下出现“黑图标”
现象:切到暗色模式后,其它文字和控件都正常,唯独某些图标仍然是深色,在深色背景上看不清。
原因:这些 SVG 文件内部 fill 被写死成了具体颜色值,比如fill="#000000",没有使用 currentColor。外部 CSS 改不动它。
解决:对单色目录下的文件做批量替换,把固定的 fill 改成 currentColor。注意只处理单色图标目录,品牌目录不要碰:
# 把 services 和 products 下的黑色 fill 替换为 currentColor find assets/icons/services assets/icons/products -name "*.svg" \ -exec sed -i '' 's/fill="#000000"/fill="currentColor"/g' {} +这条命令用 find 定位目录下的所有 SVG,再交给 sed 做替换。macOS 的 sed 需要-i ''表示原地修改且不留备份,Linux 上则是-i,两边的写法差异不要记混。如果文件里不是#000000而是其它颜色,把正则里的色值换成实际出现的值,或者写一个更通用的正则把所有固定色值都替换掉。替换完成后回到页面刷新,图标就会跟着 CSS color 走了。
5.3 官方图标更新后出现悬空引用,页面报错
现象:某次更新图标集合后,页面控制台出现找不到 symbol 的错误,某个位置空白,别的页面却正常。原因往往是官方把服务改名或合并了,比如云服务从旧名称迁移到新品牌,图标文件名对应变化,而你的代码还在引用旧的 id。
解决:更新集合前先建立清单,更新时做一次差异对比。我在工程里维护一份 manifest.json,记录所有 icon id;更新后执行下面的命令,直接看哪些被删除、哪些新增:
diff <(jq -r '.[].id' manifest.old.json) <(jq -r '.[].id' manifest.new.json)命令把两个清单的 id 字段各自提取出来做 diff,新增的以>开头,删除的以<开头。看到被删除的 id 后,在代码里全局搜索对应引用,改成新 id 或替代图标。养成这个习惯后,官方升级就不再是猜谜了。
5.4 品牌标识被随意改色、变形
现象:对外展示或宣传页里出现了被改成纯黑、加了投影或旋转了角度的 Microsoft 标识,视觉上很别扭,而且有合规风险。
原因:开发把品牌标识当成普通 UI 图标,顺手就套用了图标的样式规则。品牌标识和功能图标的法律属性完全不同,前者是商标,颜色和比例是识别要素。
解决:在项目规范里明确三类图标的处理权限:
| 图标类型 | 可改色 | 可变形 | 可加投影/效果 | | 功能图标(单色) | 是 | 否 | 有限可以 | | 云服务资源图标 | 否 | 否 | 否 | | 商标/品牌标识 | 否 | 否 | 否 |
判断标准很简单:它代表的是“一个服务”还是“一家公司的正式标识”。云服务资源图标虽然也是品牌色,但多数使用场景允许跟随主题;商标则永远原样展示。给 brands 目录单独加一份 README,写明禁止改色、变形、加效果,比口头传达可靠得多。
5.5 Sprite 引入后全局样式被污染
现象:引入 sprite.svg 之后,页面里所有 svg 元素突然全变了,要么统一变成红色,要么尺寸异常、出现奇怪边框。
原因:全局 CSS 里存在针对 svg 或 path 元素的选择器,比如某个样式重置里写了svg { fill: red; }或svg { width: 100%; },而 sprite 里的 symbol 也被这些规则命中,导致所有引用图标的样式错乱。
解决:在所有图标上有统一的作用域类名,样式只写在类名下,不要写裸露的元素选择器。正确的写法是.ui-icon path { ... },而不是path { ... }。同时排查是否给 svg 设置了全局尺寸,sprite 本身应该在隐藏状态,它的显示完全交给使用场景里的.ui-icon控制。加一个线上检查脚本,扫描构建产物里有没有裸的 svg 选择器,能在预防层面拦住这个问题。
6. 把图标集沉淀成原子化资源:命名规范、校验与增量更新
工程接完之后,真正拉开项目间差距的是维护流程。图标这种东西,今天加一个、明天改一个,没有规范就会慢慢腐烂成谁都不敢动的一块。我把这套集合在团队里沉淀成了一套固定流程,核心是三件事:命名、校验、增量更新。
命名规范决定了所有自动化脚本的稳定性。我推荐用简短前缀区分图标来源:
| 文件名模式 | 适用 | 示例 | | az- 前缀 | Azure 云资源 | az-vm.svg、az-storage.svg | | ms- 前缀 | Microsoft 产品 | ms-teams.svg、ms-onedrive.svg | | brand- 前缀 | 品牌标识 | brand-microsoft.svg |
文件名统一用小写连字符,不要用空格和驼峰。这样脚本处理时不需要额外转换,也不会因为大小写问题产生重复 id。
校验这一步复用第 3 章的 check 脚本,把它挂到 Git 钩子上,让每次提交前自动检查:
npx husky add .husky/pre-commit "node scripts/check-icons.mjs"这条命令把校验脚本注册为 pre-commit 钩子,任何缺 viewBox、缺 title 或不是合法 SVG 的文件都会在提交前被拦截。别小看这个动作,它让图标集合的完整性从“靠人记”变成了“靠机器查”。
增量更新的流程我已经固化成五步:下载官方新包、解压到临时目录、用第 5.3 节的 diff 方法对比新旧清单、更新 manifest、重新跑校验和 Sprite 构建。整个过程只要几分钟,但前提是命名规范和校验脚本都存在。
我现在的习惯是,新项目开工先花十分钟把图标目录建好、把校验脚本挂上钩子,而不是等界面做完再回头补。这一步偷懒,后面每一次图标变更都会是查不清原因的线上问题,这是我交过学费换来的经验。先把流程固化下来,以后再接 Azure、Microsoft 的新图标,就真的只是一次 diff 的事。希望帮到你。
本文还有配套的精品资源,点击获取