Material Symbols ships as three variable fonts, Outlined, Rounded and Sharp, built from the 24 px Material Icons designs. Four axes vary in CSS: optical size 20 to 48 (default 24), weight 100 to 700 (regular 400), grade -50 to 200 (default 0) and fill 0 to 100 (default 0). Google suggests grade -50 for reversed contrast such as light icons on a dark background, and says the fill axis can be animated to show user selection. Google's Fonts docs add that grade can match a text font's grade and a high grade can emphasize a symbol; only the 20 and 24 px sizes are aligned to the pixel grid.
Treating icons as a variable font lets one drawing follow the type's weight and the background's contrast. Fill becomes a state signal instead of a second icon set.
Apps and dashboards with selected states, products shown in light and dark themes, dense data UI, teams that want icons tuned rather than redrawn
Steal it for your brand
The same system, written in your colors, type and shapes. Nothing of Google's look comes with it.
typography.body.weight so icons match the body text.style.radius is under 2 px.palette.ink muted; on selection, animate fill from 0 to 1 and switch the color to palette.accent.palette.night backgrounds, draw icons in palette.on night and drop grade to -25 so light strokes don't bloom; never change weight to compensate.{
"recipe": {
"weight": "{typography.body.weight}",
"grade_on_paper": 0,
"grade_on_night": -25,
"fill_rest": 0,
"fill_selected": 1,
"optical_size_px": 24,
"corner_style": {
"by": "style.button_shape",
"map": {
"pill": "rounded",
"rounded": "outlined"
},
"default": "outlined"
},
"color": "{palette.ink_muted}",
"color_selected": "{palette.accent}",
"color_on_night": "{palette.on_night}",
"fill_transition_ms": {
"by": "style.motion",
"map": {
"calm": 300,
"crisp": 150,
"playful": 220
},
"default": 200
},
"sharp_when_radius_below_px": 2
},
"fallbacks": {
"palette.on_night": "{palette.paper}",
"palette.ink_muted": "{palette.ink}",
"palette.night": "{palette.ink}",
"style.radius": 8
},
"steps": [
"Use an open variable icon font with fill, weight, grade and optical-size axes, and set its weight to {typography.body.weight} so icons match the body text.",
"Choose the style by shape: rounded terminals when buttons are pills, the outlined default for rounded buttons, and sharp corners when {style.radius} is under 2 px.",
"Draw resting icons unfilled in {palette.ink_muted}; on selection, animate fill from 0 to 1 and switch the color to {palette.accent}.",
"On {palette.night} backgrounds, draw icons in {palette.on_night} and drop grade to -25 so light strokes don't bloom; never change weight to compensate.",
"Raise grade, not weight or size, to emphasize a single icon in a row.",
"Render at the 20 or 24 px optical sizes for small UI so strokes stay on the pixel grid."
]
}The lesson
Treat icons as a variable font with sliders, so one drawing can match any text weight, state and background.
A Customize panel on the left of the icon browser holds a Fill toggle, a Weight slider from 100 to 700, a Grade slider from -25 (low) to 200 (high emphasis), and an Optical Size slider from 20px to 48px. The grid at right shows outlined icons such as Search, Home, Menu, Close and Settings.
Don't expect to ship a variable icon font unless your team has the tooling. Keep one weight setting that matches body text and one fill state for selection.