Skip to content

Icon Button

Edit on GitHub

Compact action buttons using an icon without a text label, for toolbars, media overlays, and navigation.

@volvo-cars/css v2.5.1@volvo-cars/react-icons v4.0.0

IconButton renders a 40×40px button with a 16×16px icon. Because it has no visible label, provide aria-label or aria-labelledby.

Show codeHide code
import { IconButton } from '@volvo-cars/react-icons';
export function IconButtonVariants() {
return (
<div className="flex flex-wrap gap-16 items-center">
<IconButton icon="x" aria-label="Close" variant="filled" />
<IconButton icon="x" aria-label="Close" variant="outlined" />
<IconButton icon="x" aria-label="Close" variant="clear" />
</div>
);
}

High emphasis. Use on media surfaces (images, video) to guarantee contrast.

Medium emphasis. Default variant. Use when the button needs more prominence than clear but less than filled.

Low emphasis. Only use where context and placement make the interactive nature obvious, such as navigation bars.

  • destructive: delete, remove, or cancel actions. Available on all variants.
  • subtle: gray surface with primary text. Filled only.

Omit color for the default neutral appearance.

Clear icon buttons in medium size (default) take up 40×40 px. Set bleed to add negative margin so the button visually aligns with surrounding content while retaining the full 40×40 px touch area and hover state. Only available on the clear variant.

Pass href to render an <a> instead of a <button>.

Use asChild to render onto a framework link component like Next.js Link:

import { IconButton } from '@volvo-cars/react-icons';
import Link from 'next/link';
<IconButton icon="cogs" aria-label="Settings" asChild>
<Link href="/settings" />
</IconButton>;

Buttons that toggle state should update aria-label to describe the resulting action rather than using aria-pressed. Set data-color-mode="dark" when the button sits on dark media.

Prefer the disabled prop (which sets aria-disabled) over the native disabled attribute. It keeps the button focusable for screen readers and prevents click events internally. Disabled icon buttons get reduced opacity automatically.

Pre-built icon buttons with translated accessible labels are available from @volvo-cars/react-icons/localized. These require @volvo-cars/react-locale-provider to be set up in your app.

ShowPasswordIconButton and PlayPauseIconButton are stateful. Their icon and accessible label change based on the passwordVisible or paused prop.

Available localized buttons:

ComponentIconPurpose
BackIconButtonarrow-backNavigate back
CloseIconButtonxClose dialogs/overlays
ForwardIconButtonarrow-forwardNavigate forward
NextIconButtonchevron-forwardNext item/page
PrevIconButtonchevron-backPrevious item/page
PlayIconButtonplayPlay media
PlayPauseIconButtonplay/pauseToggle play/pause
ShowPasswordIconButtoneyeToggle password visibility

These buttons automatically provide localized aria-label values based on the current locale from LocaleProvider.

Key consumer responsibilities from the WCAG audit:

  • Accessible name required: every icon button needs aria-label or aria-labelledby. The label should describe the action (“Close”, “Delete”), not the icon (“X”, “Trash”).
  • Sufficient contrast: icon and background must meet 4.5:1 contrast. Use filled buttons on media surfaces; never use clear or outlined on images or video.
  • Bleed spacing: when using bleed, ensure enough surrounding space for the full 40×40 px touch area.
  • Toggle buttons: for play/pause or similar toggles, update aria-label to describe the resulting action rather than the current state.
PropTypeRequiredDefault
icon"code" | "link" | "map" | "menu" | "search" | "...-
The icon to render in the IconButton using the 1.0 icon system.
iconFilledboolean--
Use the filled variant of the icon, typically for active or selected states.
iconLoading"eager" | "lazy"-lazy
The loading strategy for the icon image.
color"neutral" | "destructive" | "subtle"-neutral
The color of the IconButton
size"medium" | "large"-medium
The size of the IconButton. - `'medium'` — 40 px button, 16 px icon - `'large'` — 48 px button, 24 px icon
disabledboolean--
Disables the button. Avoid using disabled buttons whenever possible - instead show error messages explaining the next steps the user should take.
classNamestring--
Custom class name, merged with existing classes.
hiddenboolean--
idstring--
titlestring--
dirstring--
langstring--
slotstring--
styleCSSProperties--
tabIndexnumber--
variant"outlined" | "filled" | "clear"-outlined
The visual style of the IconButton.
bleedboolean-false
Allows the background to bleed out into the surrounding layout, leaving the button to only take up the space for the icon itself. Only supported on the `clear` variant.
aria-labelstring--
Defines a string value that labels the current element. @see aria-labelledby.
aria-labelledbystring--
Identifies the element (or elements) that labels the current element. @see aria-describedby.
hrefstring--
onClickMouseEventHandler<HTMLButtonElement>--
Called when the button is clicked. If used within a `<form>`, prefer to set the button to `type=submit` and use the `onSubmit` event on the form instead.
formstring--
Id of a form element that this button should be associated with. Defaults to the containing form element.
formActionstring--
The URL that processes the information submitted by the button, overriding the `action` attribute of the button's form.
formMethod"post" | "get"--
Specifies the HTTP method used to submit the form, overriding the `method` attribute of the button's form.
namestring--
The name of the button, submitted as a pair with the button's value as part of the form data.
valuestring--
The value associated with the button's `name` in the form data when the form is submitted using this button.
type"button" | "submit"-button
onBlurFocusEventHandler<HTMLButtonElement>--
onFocusFocusEventHandler<HTMLButtonElement>--
onKeyDownKeyboardEventHandler<HTMLButtonElement>--
onKeyUpKeyboardEventHandler<HTMLButtonElement>--
onPointerDownPointerEventHandler<HTMLButtonElement>--
onPointerEnterPointerEventHandler<HTMLButtonElement>--
onPointerLeavePointerEventHandler<HTMLButtonElement>--
onPointerMovePointerEventHandler<HTMLButtonElement>--
onPointerUpPointerEventHandler<HTMLButtonElement>--
onAnimationEndAnimationEventHandler<HTMLButtonElement>--
onAnimationStartAnimationEventHandler<HTMLButtonElement>--
onTransitionEndTransitionEventHandler<HTMLButtonElement>--
asChildboolean-