Use a <button> for a filled common button, or an
<a class="button"> for a link that looks the same. Put an
<span class="material-symbols" aria-hidden="true"> icon before or after the label and wrap the label in its own
<span>. The order of the two spans sets the
placement. There is no icon-left or
icon-right class. An icon-only button needs an aria-label,
because the icon is hidden from assistive technology. Add circle for a round
common button. Icon buttons are
.icon-button.
A button has two independent axes: a style
(filled, tonal, outlined,
elevated, text) and a
size (xsmall through
xlarge). Any style combines with any size. That takes
nine classes instead of twenty-five, because the size sets the
geometry and the style sets the color.
Tokens follow the
M3 button spec.
The default is the small size: 40dp tall, a
label-large label, fully round corners, a 20dp icon on an
8dp gap, and a symmetric 16dp inset. State layers are 8% on hover and
10% on focus or press. A disabled button uses on-surface
at 38% on a 12% container.
A label that does not fit wraps between words, and the button grows
taller. With enlarged text, 200% zoom or a narrow column, the label stays
inside the button and the button stays inside its parent. The size's height
is the minimum, so a label that fits looks the same. Keep the label
in its own <span> so a single word longer than the
parent can break as well. These stay on one line at a fixed height:
circle buttons, FABs, extended
FABs, Timepicker AM/PM controls, and buttons in button groups, split
buttons, toolbars, top app bars, dialog and sheet headers, navigation bars and rails, tabs,
pagination and snackbars. If a rule
gives a button a smaller height, set
min-height too, or set
--md-comp-filled-button-container-height instead.
<button>Create</button>
<button>
<span class="material-symbols" aria-hidden="true">add</span><span>Create</span>
</button>
<button>
<span>Send</span><span class="material-symbols" aria-hidden="true">send</span>
</button>
<button class="circle" aria-label="Add">
<span class="material-symbols" aria-hidden="true">add</span>
</button>
<a class="button" href="/docs">Link</a>
Filled
Filled is the default, high-emphasis style, for the main action on a page.
The container is primary, the label is
on-primary, and there is no elevation. It also has its
own class, filled, so all five styles have a name.
Adding it changes nothing.
<button>Create</button>
<button class="filled">Create</button>
<button>
<span class="material-symbols" aria-hidden="true">add</span><span>Create</span>
</button>
<a class="button" href="/docs">Link</a>
Tonal
Add tonal for medium emphasis. The container is
secondary-container and the label is
on-secondary-container.
<button class="tonal">Create</button>
<button class="tonal">
<span class="material-symbols" aria-hidden="true">add</span><span>Create</span>
</button>
Outlined
Add outlined (or border) for medium
emphasis with no fill. The outline is outline and the
label is primary.
<button class="outlined">Create</button>
Elevated
Add elevated for medium emphasis with a shadow. The container is
surface and the label is primary, with
elevation 1 at rest and 2 on hover. Use it sparingly so the page
does not fill with shadows.
<button class="elevated">Create</button>
Text
Add text for low emphasis. It has no container, and the
label is primary. Use text buttons inside cards and
dialogs so they do not stack shadows.
<button class="text">Create</button>
Icon buttons
.icon-button is its
own component. circle on a common button is the older
round common-button form and still works. It follows the size
scale, 40dp by default. The variant helpers still apply. The
default is filled, text gives the standard
(transparent) icon button, and tonal and
outlined match the common-button colors.
<button class="circle" aria-label="Add">
<span class="material-symbols" aria-hidden="true">add</span>
</button>
<button class="circle tonal" aria-label="Add">…</button>
<button class="circle outlined" aria-label="Add">…</button>
<button class="circle text" aria-label="Add">…</button>
Floating
For a FAB, use circle extra or circle large.
It is 56dp with 16dp corners, primary-container and elevation 3.
extra circle medium is the 80dp medium one (20dp
corners, 26dp icon), and extra circle large is the 96dp
large one (28dp corners, 36dp icon). The large size needs the
extra, because circle large on its own is the
alias for the default 56dp FAB.
Use extend small for the extended FAB, an icon and a
label at 56dp, with 16dp corners and 8dp between the two. It takes the
three explicit sizes. extend small is 56dp on a
symmetric 16dp inset, extend medium is 80dp (20dp
corners, 28dp icon) and extend large is 96dp (28dp
corners, 36dp icon). Each uses the label role Material gives it.
Its container colour is also a role. Adding
secondary-container or
tertiary-container recolours the label and the state
layers to match. See the FAB page
for the whole axis.
<button class="circle extra" aria-label="Add">
<span class="material-symbols" aria-hidden="true">add</span>
</button>
<button class="circle extra medium" aria-label="Add">
<span class="material-symbols" aria-hidden="true">add</span>
</button>
<button class="circle extra large" aria-label="Add">
<span class="material-symbols" aria-hidden="true">add</span>
</button>
<button class="extend small">
<span class="material-symbols" aria-hidden="true">add</span><span>Create</span>
</button>
<button class="extend medium">
<span class="material-symbols" aria-hidden="true">add</span><span>Create</span>
</button>
<button class="extend large secondary-container">
<span class="material-symbols" aria-hidden="true">add</span><span>Create</span>
</button>
Sizes
Buttons come in five sizes. small is the default at 40dp with a 20dp
icon, so it needs no class. The rest are
xsmall (32dp, 20dp icon),
medium (56dp, 24dp, title-medium label),
large (96dp, 32dp, headline-small) and
xlarge (136dp, 40dp, headline-large).
The inset and the icon gap grow with the size, and an
outlined button's border thickens with it:
1dp up to medium, 2dp at large and 3dp at extra large.
circle follows the
same size scale. A round common button takes both the box
and the icon size of its step, 40dp with a 20dp icon by
default and 136dp with a 40dp icon at xlarge. Only
circle extra and circle large leave this
scale, because they are FAB sizes with a scale of their own. For the
icon button's numbers, 40dp with a 24dp icon, use
.icon-button.
<button class="xsmall">Extra small</button>
<button>Small</button>
<button class="medium">Medium</button>
<button class="large">Large</button>
<button class="xlarge">Extra large</button>
Write the two axes side by side. There is no per-combination class, so any style works with any size.
<button class="tonal medium">Tonal medium</button>
<button class="outlined xsmall">Outlined extra small</button>
<button class="text medium">Text medium</button>
For a form submit, use a real <button type="submit">
rather than an input.
<button type="submit">
<span>Submit</span><span class="material-symbols" aria-hidden="true">send</span>
</button>
Shape and toggles
Buttons are round. Add square for the squared corner
of the size: 12dp up to small, 16dp at medium and 28dp at large and
extra large. When pressed, every common button morphs its corners to the
pressed shape of its size (8dp up to small, 12dp at medium and 16dp
beyond) and springs back on release.
<button>Round</button>
<button class="square">Square</button>
<button class="tonal square medium">Square medium</button>
Add aria-pressed to make a button a toggle. When selected, a round
button goes square and a square one goes round, so the cue does not
rely on colour alone. The colours change too: filled from
surface-container to primary, tonal from secondary-container to
secondary, outlined to inverse-surface without its outline, and
elevated to primary. Text buttons do not toggle. Switch
aria-pressed in your click handler. For a set of
toggles that share a row, use a
button group.
<button type="button" aria-pressed="false">Filled</button>
<button type="button" aria-pressed="true">Filled</button>
<button type="button" class="tonal" aria-pressed="true">Tonal</button>
<button type="button" class="outlined" aria-pressed="true">Outlined</button>
<button type="button" class="elevated square" aria-pressed="true">Elevated square</button>
Disabled
Use the disabled attribute, or the
disabled class on a link. It applies to every variant.
<button disabled>Filled</button>
<button class="tonal" disabled>Tonal</button>
<a class="button disabled">Link</a>