System of icons and pictograms
1) The role of icons in the product
Icons are a compact carrier of meaning and state. They speed up scanning, help save space and increase pattern recognition. In product interfaces, the icon complements text and color, rather than replacing them.
Principles:1. Meaning> style: each icon must have a clear application scenario.
2. Consistency: single grid, stroke, angles, filling rhythm.
3. Availability: the icon is not the only signal; there is always a signature/tooltip/aria.
4. Performance: one SVG pipeline, sprites and color/size tokens.
2) Grid and key lines
Basic artboards: 16 × 16, 20 × 20, 24 × 24 (main), 32 × 32.
Keyline-A circle/square inscribed at 1-2 px for optical balance.
Pixel pitch: draw on integer coordinates; stroke is a multiple of 0. 5 px (usually 1. 5 px at 24 × 24).
- Diagonals "thicker" look thinner - add 0. 25 px to stroke in trouble spots.
- We slightly sink the tops of sharp corners inside the keyline by 1 px so as not to "rattle."
- Circles and dots often require + 1 px to diameter for equal visual mass.
Click zones: interactive zone ≥ 40 × 40 px (mobile), ≥ 32 × 32 px (desktop); the icon is centered.
3) Typesetting style
Default outline:- stroke: 1. 5 px (24×24), 1. 25 px (20×20), 1 px (16×16).
- linecap/linejoin: 'round' for friendliness or 'miter' for technical style (fixed in the guideline).
- Radius angles in geometry: 2-3 px (by 24 × 24).
Filled-For dense areas and status icons.
Duotone is allowed for illustrative empty states, but not for critical UI signals.
- Outline - basic state.
- Filled - asset/allocation.
- Two-tone - decorative/in help.
4) Color and Contrast (WCAG)
The basic mode is monochrome via 'currentColor': the icon inherits the color of the text/context.
Critical statuses (error/success/warning) - semantic tokens:- `icon. error '↔ background ≥ 3:1, signed with text (not just color).
- `icon. on-surface '↔ background ≥ 3:1; for small sizes aim at 4. 5:1.
- On color dies, use 'on-' colors (auto contrast from the color system).
5) States and interactions
Default/Hover/Active/Disabled/Focus: the difference is not only in color - change the opacity/fill/thickness/background pill, add focus ring.
Badges - Digit contrast ≥ 4. 5:1 to the die; digit size ≥ 10-11 px.
Toggle icons (favorites, like): change the fill and/or internal point, not just the color.
6) Icon + text
Icons do not replace labels in key actions. Minimum pair: icon + short text (or tooltip by 'aria-label'). In lists and tables, the icon is aligned with the cap height of the text and the baseline.
7) Availability (A11y)
For decorative icons:' role =" img" aria-hidden =" true"' or remove accessibility from the stream.
For semantic:' <svg role =" img" aria-labelledby =" id">' +' <title id = "id "> Description </title>' or 'aria-label '.
The icon should not be the only carrier of the status: add text/hint/iconographic pattern (form, stroke).
Text size and signature contrast correspond to WCAG (regular ≥ 4. 5:1).
8) SVG pipeline and performance
Why SVG: vector clarity, styling via CSS, light weight with optimization.
Recommendations:- Store master files in Figma, export to SVG with options: without extra 'group', without 'fill-rule' by default, with the'viewBox' attribute and without fixed 'width/height' (override in CSS).
- Run through SVGO (project profile): deleting metadata, reducing coordinates, merging paths.
- Abandoning icon fonts - accessibility and rendering issues.
1. SVG sprite:
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>
cheap repetitions, − you can't easily change the'stroke-width' in some pipelines.
2. Inline-SVG (React component): flexibility of styles and props, tree-shaking.
3. External '<img>' - for decorative/illustrative only.
css
.i { width: 1em; height: 1em; color: var(--icon-color, currentColor); }
.i--muted { opacity:.64; }
.i--danger { color: var(--role-danger); }
9) Component API (React example)
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;
};
Behavior:
- By default,' size =" 1em"' and 'stroke = 1. 5`.
- If' decorative', add 'aria-hidden =" true"'.