All icon styles
Google icon style

What Google does

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.

Google's system, as published

Styles
Outlined, Rounded, Sharp
Opsz
20 to 48, default 24
Wght
100 to 700, regular 400
Grad
-50 to 200, default 0; -50 for reversed contrast
Fill
0 to 100 (0 to 1 in the CSS API), default 0
Pixel Grid
20 and 24 px only
Css Axes Example
opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200

Why it works

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.

Best for

Apps and dashboards with selected states, products shown in light and dark themes, dense data UI, teams that want icons tuned rather than redrawn

What breaks it

  • Shipping a separate filled icon set when the fill axis covers it
  • Thickening icons with weight on dark backgrounds instead of lowering grade
  • Mixing outlined and rounded styles in one layout

Sources

  • github.com: README: three styles, axis ranges and defaults, grade for reversed contrast, fill animated for selection, pixel-grid sizes
  • developers.google.com: Material Symbols guide: axis ranges in the CSS2 API, grade matched to text grade, high grade for emphasis

Steal it for your brand

The same system, written in your colors, type and shapes. Nothing of Google's look comes with it.

The recipe

  1. 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.
  2. 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.
  3. Draw resting icons unfilled in palette.ink muted; on selection, animate fill from 0 to 1 and switch the color to palette.accent.
  4. 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.
  5. Raise grade, not weight or size, to emphasize a single icon in a row.
  6. Render at the 20 or 24 px optical sizes for small UI so strokes stay on the pixel grid.

What you'll need

  • Which icons have a selected state
  • Whether the piece has dark sections
Recipe as JSON
{
  "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."
  ]
}

See it working

  • Google: The customizer panel: drag fill, weight, grade and optical size and watch the same icon change

The lesson

Treat icons as a variable font with sliders, so one drawing can match any text weight, state and background.

The move

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.

Why it works

  • Our readPutting the axes next to the icons lets a designer see each setting change at once.
  • Our readLabeling the grade ends as low and high emphasis tells the viewer what the setting is for.
  • Our readA single outlined style across Search, Home and Settings shows one family, so the sliders can be applied to all of them.

What not to copy

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.

More from Google

More icon styles