图标和象形图系统
1)图标在产品中的作用
图标是意义和状态的紧凑载体。它们可加快扫描速度,帮助节省空间并提高模式的可识别性。在产品界面中,图标补充文本和颜色,而不是替换它们。
原则:1.含义>样式:每个图标必须具有清晰的应用脚本。
2.一致性:单网格、笔触、角度、填充节奏。
3.可用性:图标不是唯一的信号;总是有签名/tooltip/aria。
4.性能:单个SVG管道、精灵和颜色/大小令牌。
2)网格和关键线
基本艺术品:16 × 16、20 × 20、24 × 24(主要)、32 × 32。
键线(keyline):圆形/正方形,刻有1-2 px缩进,用于光学平衡。
像素间距:在整个坐标上绘制;stroke简称0。5 px(通常1。5 px 24 × 24)。
- 对角线"厚"看起来更薄-添加0。25 px到stroke在有问题的地方。
- 尖角的顶点在1 px处向内加热键线,以免发出"响尾蛇"。
- 圆圈和圆点通常需要+1 px的直径才能达到相等的视觉质量。
点击区域:互动区域≥ 40 × 40 px(移动),≥ 32 × 32 px(桌面);图标居中。
3)招聘风格
缺省线性(outline):- stroke: 1.5 px (24×24), 1.25 px (20×20), 1 px (16×16).
- linecap/linejoin:"round"是为了友好,或"miter"是为了技术风格(固定在天线中)。
- 几何半径角:2-3 px (24 × 24)。
填色(filled)-用于密集区域和状态图标。
双音(duotone)-允许用于说明性空状态,但不允许用于关键UI信号。
- Outline-基本状态。
- Filled-资产/分配。
- Two-tone-装饰/参考。
4)颜色与对比(WCAG)
基本模式是通过"currentColor"进行的单色:图标继承文本/上下文的颜色。
关键状态(错误/成功/警告)-语义令牌:- `icon.error' ↔背景≥ 3:1,带有文字签名(不仅仅是颜色)。
- `icon.on-surface '↔背景≥ 3:1;小尺寸瞄准4。5:1.
- 在彩色条纹上,使用"on-"颜色(来自颜色系统的对比度自动子板)。
5)状态和互动
Default/Hover/Active/Disabled/Focus:差异不仅在于颜色-我们改变不透明/填充/厚度/背景锯齿,我们添加焦点环。
Badges(计数器):数字对比度≥ 4.5:1 to plash;数字大小≥ 10-11 px。
Toggle图标(收藏夹、喜欢):我们更改填充和/或内部点,而不仅仅是颜色。
6)图标+文字
图标不会在关键动作中替换标签。最小配对:图标+短文本(或"aria-label"上的工具集)。在列表和表中,图标将按文本和基线的顶点对齐。
7)可用性(A11y)
对于装饰图标:'role="img" aria-hidden="true"或从可用性流中删除。
对于语义:'<svg role='img' aria-labelledby='id'>'+'<title id='id'>描述</title>'或'aria-label'。
图标不应是状态的唯一载体:添加文本/提示/图像模式(形状,笔画)。
文本大小和签名对比度对应于WCAG(普通≥ 4。5:1).
8) SVG管道和性能
为什么SVG:矢量清晰,通过CSS造型,轻量级优化。
建议:- 将主文件存储在Figma,导出到SVG,并带有选项:没有多余的"组"、缺省的"fill-rule"、属性"viewBox"和没有固定的"width/height"(在CSS中覆盖)。
- 通过SVGO(项目配置文件)运行:删除元数据、缩短坐标、合并路径。
- 拒绝使用图标字体(icon fonts)-可用性和渲染性问题。
1.SVG精灵:
html
<svg style="display:none">
<symbol id="icon-upload" viewBox="0 0 24 24">…</symbol>
</svg>
…
<svg class="i"><use href="#icon-upload"></use></svg>
便宜的重播,−某些吹笛线上不能轻易改变"stroke-width"。
2.Line-SVG (React组件):样式和props的灵活性,树摇摆。
3.外部"<img>'-仅用于装饰/插图。
css
.i { width: 1em; height: 1em; color: var(--icon-color, currentColor); }
.i--muted { opacity:.64; }
.i--danger { color: var(--role-danger); }
9)组件的API (React示例)
tsx type IconProps = {
name: 'upload' 'download' 'wallet' 'trophy' 'shield' string;
size?: number '1em' 'sm' 'md' 'lg';
stroke?: number; // 1 1. 25 1. 5 title?: string; // для a11y decorative?: boolean; // если true -> aria-hidden className?: string;
};
行为:
- 默认情况下,"size="1em"和'stroke=1。5`.
- 如果"装饰"-我们添加"aria-hidden="true"。