---
name: material-symbols-v3
description: Material Symbols v3 variable icon font system. Use when adding icons to buttons, navigation, status indicators, or any UI element. Provides 2,500+ icons with fill, weight, grade, and optical size axes. Integrates with project color tokens.
allowed-tools: Read, Write, Edit, Glob, Grep
---
# Material Symbols v3
Material Design 3 icon system using variable fonts. This project uses Material Symbols Outlined loaded from Google Fonts CDN.
## Related Skills
- **`ux-iconography`**: UX patterns for icon usage, accessibility, and animations
- **`ux-accessibility`**: ARIA requirements for icon-only buttons
- **`utopia-fluid-scales`**: Type scale tokens for fluid icon sizing
## Project Setup
Location: `css/styles/icons.css`
```css
@import url('https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap');
```
### Self-Hosting (Offline)
For offline/production without CDN:
1. Download from [fonts.google.com/icons](https://fonts.google.com/icons)
2. Place in `/fonts/material-symbols-outlined.woff2`
3. Replace CDN import:
```css
@font-face {
font-family: 'Material Symbols Outlined';
src: url('/fonts/material-symbols-outlined.woff2') format('woff2');
font-weight: 100 700;
font-style: normal;
}
```
---
## Basic Usage
```html
home
settings
favorite
```
Use the icon name from [Material Symbols](https://fonts.google.com/icons) as text content.
---
## Icon Sizes
| Class | Size | Optical Size | Use Case |
|-------|------|--------------|----------|
| `.icon--sm` | 20px | 20 | Dense UI, inline text |
| `.icon--md` | 24px | 24 | Default, buttons |
| `.icon--lg` | 40px | 40 | Emphasis, headers |
| `.icon--xl` | 48px | 48 | Hero sections |
```html
info
info
info
info
```
### Fluid Sizing with Utopia
For icons that scale with typography:
```css
.icon-fluid {
font-size: var(--step-1);
--icon-optical-size: 24;
}
```
---
## Variable Font Axes
Material Symbols is a **variable font** with 4 axes:
| Axis | Range | Default | Purpose |
|------|-------|---------|---------|
| `FILL` | 0–1 | 0 | Outlined (0) vs filled (1) |
| `wght` | 100–700 | 400 | Stroke weight |
| `GRAD` | -25–200 | 0 | Fine thickness adjustment |
| `opsz` | 20–48 | 24 | Optical size optimization |
### Fill Styles
```html
favorite
favorite
```
### Weight Variants
```html
home
home
home
home
home
```
### Grade Variants
```html
home
home
home
```
### Custom Variation
```css
.custom-icon {
--icon-fill: 1;
--icon-weight: 600;
--icon-grade: 0;
--icon-optical-size: 24;
}
```
---
## Icon Colors
### Semantic Colors
```html
check_circle
info
block
```
### Inherit from Parent
```css
.icon {
color: inherit; /* Default behavior */
}
.btn-primary .icon {
color: var(--theme-on-primary);
}
```
### State Colors
```css
.icon-success { color: var(--color-success); }
.icon-error { color: var(--color-error); }
.icon-warning { color: var(--color-warning); }
```
---
## Interactive Icons
```html
settings
```
```css
.icon--interactive {
cursor: pointer;
transition: color 0.2s ease, transform 0.2s ease;
}
.icon--interactive:hover {
color: var(--icon-color-primary);
transform: scale(1.1);
}
.icon--interactive:active {
transform: scale(0.95);
}
```
---
## Button Patterns
### Icon + Text Button
```html
```
```css
.btn {
display: inline-flex;
align-items: center;
gap: var(--space-xs);
}
```
### Icon-Only Button
```html
```
```css
.btn-icon {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: var(--min-touch-target);
min-height: var(--min-touch-target);
padding: var(--space-xs);
}
```
### Trailing Icon
```html
```
---
## Accessibility
### Decorative Icons (with visible label)
```html
```
### Meaningful Icons (icon-only)
```html
```
### Screen Reader Text
```html
```
### High Contrast Mode
```css
@media (forced-colors: active) {
.icon {
forced-color-adjust: auto;
}
}
```
---
## Common Icons Reference
### Navigation
| Icon | Name | Usage |
|------|------|-------|
| home | `home` | Home/main |
| menu | `menu` | Hamburger menu |
| arrow_back | `arrow_back` | Back navigation |
| arrow_forward | `arrow_forward` | Forward/next |
| close | `close` | Close/dismiss |
### Actions
| Icon | Name | Usage |
|------|------|-------|
| add | `add` | Create new |
| edit | `edit` | Edit/modify |
| delete | `delete` | Remove |
| save | `save` | Save |
| search | `search` | Search |
### Status
| Icon | Name | Usage |
|------|------|-------|
| check_circle | `check_circle` | Success/complete |
| error | `error` | Error state |
| warning | `warning` | Warning |
| info | `info` | Information |
| help | `help` | Help |
### Media
| Icon | Name | Usage |
|------|------|-------|
| play_arrow | `play_arrow` | Play |
| pause | `pause` | Pause |
| volume_up | `volume_up` | Sound on |
| volume_off | `volume_off` | Sound off |
### Settings
| Icon | Name | Usage |
|------|------|-------|
| settings | `settings` | Settings |
| tune | `tune` | Adjustments |
| brightness_6 | `brightness_6` | Theme toggle |
| lock | `lock` | Locked/secure |
Browse all icons: [fonts.google.com/icons](https://fonts.google.com/icons)
---
## Animation
### With Anime.js
```javascript
import { animate } from 'animejs';
// Wiggle
animate(iconEl, {
rotate: [0, -10, 10, -10, 10, 0],
duration: 300,
ease: 'easeOutQuad'
});
// Bounce
animate(iconEl, {
scale: [1, 1.2, 1],
duration: 200,
ease: 'easeOutBack'
});
```
### CSS Transitions
```css
.icon {
transition: transform 0.15s ease;
}
.btn:hover .icon {
transform: scale(1.1);
}
.btn:active .icon {
transform: scale(0.95);
}
```
---
## Web Component Wrapper
```javascript
class MIcon extends HTMLElement {
static observedAttributes = ['name', 'size', 'filled'];
connectedCallback() {
this.render();
}
attributeChangedCallback() {
this.render();
}
render() {
const name = this.getAttribute('name') || 'help';
const size = this.getAttribute('size') || 'md';
const filled = this.hasAttribute('filled');
this.innerHTML = `${name}`;
}
}
customElements.define('m-icon', MIcon);
```
Usage:
```html
```
---
## CSS Custom Properties
```css
:root {
/* Font */
--icon-font: 'Material Symbols Outlined';
/* Sizes */
--icon-size-sm: 20px;
--icon-size-md: 24px;
--icon-size-lg: 40px;
--icon-size-xl: 48px;
/* Variable font axes */
--icon-fill: 0;
--icon-weight: 400;
--icon-grade: 0;
--icon-optical-size: 24;
/* Colors */
--icon-color: var(--color-on-surface);
--icon-color-primary: var(--color-primary);
--icon-color-secondary: var(--color-on-surface-variant);
--icon-color-disabled: var(--color-outline);
}
```
---
## Migration from Emoji
Replace emoji icons with Material Symbols:
| Old (Emoji) | New (Material Symbol) |
|-------------|----------------------|
| `📖` | `menu_book` |
| `⚙️` | `settings` |
| `🏠` | `home` |
| `⭐` | `star` |
| `🔒` | `lock` |
| `🔊` | `volume_up` |
| `🔇` | `volume_off` |
| `✓` | `check` |
---
## Files
- `css/styles/icons.css` - Icon system styles and CSS custom properties