IconButton
IconButton allows users to take actions and make choices with a single click or tap. IconButtons use icons instead of text to convey available actions on a screen. IconButton is typically found in forms, dialogs and toolbars.
Some buttons are specialized for particular tasks, such as navigation or presenting menus.
Props
Additional role="link" Props
Usage guidelines
- Displaying icons that don't have actions associated with them. Use an Icon instead.
- Displaying multiple IconButtons on a surface that uses the same icon for different actions.
- Text is better suited to convey the action and/or the icon isn't quickly recognizable by users.
- Destructive, high-emphasis actions, e.g "delete", "remove".
Best practices
Use IconButton to perform low-emphasis actions, such as opening a Modal to edit a board.
Pair IconButton with a regular button to perform a high-emphasis action. IconButton should be a secondary action among regular buttons.
Consider grouping multiple actions in an "ellipsis" IconButton to avoid distraction with an overload of icons.
Display more than 4 icon buttons in a single row as it can cause cognitive load and usability issues.
Display a Tooltip in conjunction with IconButton to provide context when the icon alone would be insufficient to convey the purpose of the button.
Add an IconButton on top of images unless it has a background that ensures easy readability and accessible contrast. Check the background color variant to learn more.
Accessibility
ARIA attributes
IconButton conveys the component behavior using iconography. IconButton requires accessibilityLabel
, a text description for screen readers to announce and communicate the represented Icon. In the example below, the screen reader reads: "Create Pin menu". The label should describe the intent of the action, not the Icon itself. For example, use "Edit board" instead of "Pencil".
If IconButton is used as a control button to show/hide a Popover-based component, we recommend passing the following ARIA attributes to assist screen readers:
accessibilityControls
: informs the screen reader that IconButton controls the display of an anchored Popover-based component. It populates aria-controls.accessibilityHaspopup
: informs the screen reader that there’s a Popover-based component attached to IconButton. It populates aria-haspopup.accessibilityExpanded
: informs the screen reader whether an anchored Popover-based component is currently open or closed. It populates aria-expanded.
import { useState, useRef } from 'react'; import { Box, IconButton, Flex, Dropdown } from 'gestalt'; export default function Example() { const [open, setOpen] = useState(false); const [selected, setSelected] = useState([]); const anchorRef = useRef(null); const onSelect = ({ item }) => { if (selected.some(({ value }) => value === item.value)) { setSelected((selectedValue) => selectedValue.filter(({ value }) => value !== item.value) ); } else { setSelected((selectedValue) => [...selectedValue, item]); } }; return ( <Box padding={4}> <Flex width="100%" justifyContent="center"> <IconButton accessibilityControls="accessibility-example" accessibilityExpanded={open} accessibilityHaspopup accessibilityLabel="Create Pin Menu" bgColor="lightGray" icon="add" iconColor="darkGray" onClick={() => setOpen((prevVal) => !prevVal)} ref={anchorRef} selected={open} size="lg" tooltip={{ text: 'Create Pin', idealDirection: 'up' }} /> {open && ( <Dropdown anchor={anchorRef.current} id="accessibility-example" onDismiss={() => setOpen(false)} > <Dropdown.Section label="Create"> <Dropdown.Item onSelect={onSelect} option={{ value: 'Pin', label: 'Pin' }} selected={selected} /> <Dropdown.Item onSelect={onSelect} option={{ value: 'Story Pin', label: 'Story Pin' }} selected={selected} /> </Dropdown.Section> </Dropdown> )} </Flex> </Box> ); }
Keyboard interaction
The default behaviour for IconButton is to be focusable in sequential keyboard navigation in the order defined by the document's source order.
Use tabIndex
to remove IconButton from the sequential keyboard navigation to improve accessibility. The example below shows a common use case when two consecutive and visually different elements perform the same action. One of them, in this case IconButton, can be removed from keyboard navigation to prevent screen readers from announcing the same interaction twice.
If IconButton is disabled, it's also unreachable from keyboard navigation.
import {} from 'react'; import { IconButton, Flex, Avatar, Link, Text } from 'gestalt'; export default function Example() { return ( <Flex width="100%" height="100%" justifyContent="center" alignItems="center" gap={2} > <Avatar name="James Jones" src="https://i.ibb.co/2Fc00R3/james.jpg" size="md" /> <Flex gap={{ row: 2, column: 0 }} alignItems="center"> <Text inline weight="bold"> <Link accessibilityLabel="Open the settings page" target="blank" inline underline="none" href="https://www.pinterest.com/settings/" > James Jones </Link> </Text> <IconButton accessibilityLabel="Open the settings page" href="https://www.pinterest.com/settings/" icon="edit" role="link" size="xs" tabIndex={-1} target="blank" tooltip={{ text: 'Edit name' }} /> </Flex> </Flex> ); }
Localization
Be sure to localize accessibilityLabel
.
Variants
Role
IconButton can be use for navigation or actions.
import {} from 'react'; import { Flex, IconButton } from 'gestalt'; export default function Example() { return ( <Flex width="100%" height="100%" justifyContent="center" alignItems="center" > <IconButton accessibilityLabel="This IconButton is an example of IconButton acting as a link" icon="visit" role="link" target="blank" href="https://www.pinterest.com" tooltip={{ text: 'Link example' }} /> </Flex> ); }
If IconButton acts as a link, set role = link
and pass role-specific props.
target
is optional and defines the frame or window to open the anchor defined on href:
- "null" opens the anchor in the same window.
- "blank" opens the anchor in a new window.
- "self" opens an anchor in the same frame.
rel
is optional. Use "nofollow" for external links to specify to web crawlers not follow the link.
IconButtons that act as links can be paired with OnLinkNavigationProvider. See OnLinkNavigationProvider to learn more about link navigation.
import {} from 'react'; import { IconButton, Flex } from 'gestalt'; export default function Example() { return ( <Flex width="100%" height="100%" justifyContent="center" alignItems="center" gap={2} > <IconButton accessibilityLabel="This IconButton is an example of IconButton acting as a button" icon="share" onClick={() => {}} tooltip={{ text: 'Button Example' }} /> </Flex> ); }
If IconButton acts as a button, pass role-specific props.
Size
IconButton is available in 5 fixed sizes:
xl
(56px)
Extra large IconButtons should be used sparingly and only in places where the UI has a case for an extra-large IconButton.lg
(48px)
Large is the only size that should be used on Pinner surfaces.md
(40px)
Medium is the size used on more dense UI such as business surfaces or internal tools.sm
(32px)
Small IconButton should be used sparingly and only in places where the UI is very dense.xs
(24px)
Use sparingly and only in places where the UI is very dense or has a case for an extra-small IconButton as they can be hard to see for people with visual impairments.
Use padding sparingly. The padding options are 1-5, which represents the padding in increments of 4 pixels (2 = 8px padding). Combine the padding
with size
options for custom icon/button size ratios. If omitted, padding is derived from the default padding for each size
prop.
Icon color
IconButton can be presented in combinations of icon and background colors. In the absence of combinations, for each iconColor
or bgColor
value, a default paired value is assigned.
Follow these guidelines for iconColor
- Red ("red"). High emphasis, used for primary actions.
- Dark Gray ("darkGray"). Medium emphasis, used for secondary actions.
- Gray ("gray"). Low emphasis when placed on white backgrounds, used for tertiary actions. Medium emphasis when placed on dark backgrounds, used for secondary actions.
- White ("white"). Used in a dark mode scheme or over a dark-colored background creating better visibility.
Background color
IconButton can be presented in combinations of icon and background colors. In the absence of combinations, for each iconColor
or bgColor
value, a default paired value is assigned.
Follow these guidelines for bgColor
- Red ("red"). High emphasis, used for primary actions.
- Light Gray ("lightGray"). Medium emphasis, used for secondary actions.
- Transparent Dark Gray ("transparentDarkGray"). Medium emphasis, used for secondary actions, usually above a colored background.
- Gray ("gray"). Used for tertiary actions or in cases where the primary "red" is not an option. Medium emphasis when placed on dark backgrounds, used for secondary actions.
- White ("white"). Used when there is a need of an IconButton over an image or colored background to provide better contrast and visibility.
- Transparent ("transparent"). Used when there is a need to have an IconButton over an image without a background.
- Dark Gray ("darkGray"). Used as the selected state for IconButton.
With Tooltip
By specifying the tooltip
property, a Tooltip will automatically be triggered when IconButton is hovered or focused. If the Tooltip text
does not provide more information than the IconButton accessibilityLabel
, set the tooltip prop's accessibilityLabel
to an empty string, as seen below in the Edit example.
import {} from 'react'; import { IconButton, Flex } from 'gestalt'; export default function Example() { return ( <Flex width="100%" height="100%" justifyContent="center" alignItems="center" gap={4} > <IconButton accessibilityLabel="Sharing" icon="share" tooltip={{ text: 'This Pin is private unless you share it with others.', idealDirection: 'up', }} /> <IconButton accessibilityLabel="Edit" icon="edit" tooltip={{ text: 'Edit', accessibilityLabel: '', idealDirection: 'up', }} /> </Flex> ); }
Custom icon
IconButton accepts both Gestalt Icons and custom icons, as shown in the second example. For custom icons, follow our custom SVG icons guidelines.
import {} from 'react'; import { Flex, IconButton } from 'gestalt'; export default function Example() { return ( <Flex width="100%" height="100%" justifyContent="center" alignItems="center" gap={2} > <IconButton accessibilityLabel="Go to next steps" icon="directional-arrow-right" tooltip={{ text: 'Built-in Gestalt Icon' }} /> </Flex> ); }
import {} from 'react'; import { IconButton, Flex } from 'gestalt'; export default function Example() { return ( <Flex width="100%" height="100%" justifyContent="center" alignItems="center" gap={2} > <IconButton accessibilityLabel="Go to next steps" dangerouslySetSvgPath={{ __path: 'M23 5v14a4 4 0 0 1-4 4H5a4 4 0 0 1-4-4v-5.5h10.258l-1.94 1.939a1.5 1.5 0 0 0 2.121 2.122L17 12l-5.561-5.561a1.501 1.501 0 0 0-2.121 2.122l1.94 1.939H1V5a4 4 0 0 1 4-4h14a4 4 0 0 1 4 4', }} tooltip={{ text: 'Custom Icon' }} /> </Flex> ); }
Selected state
IconButton has a selected
state to visually indicate that the element is selected, open, and/or active. If the selected state controls the display of a Popover-based component (open/closed), use accessibilityExpanded
to inform screen reader users. See the Accessibility guidelines to learn more.
import { useState, useRef } from 'react'; import { Box, IconButton, Flex, Dropdown } from 'gestalt'; export default function Example() { const [open, setOpen] = useState(false); const [selected, setSelected] = useState([]); const anchorRef = useRef(null); const onSelect = ({ item }) => { if (selected.some(({ value }) => value === item.value)) { setSelected((selectedValue) => selectedValue.filter(({ value }) => value !== item.value) ); } else { setSelected((selectedValue) => [...selectedValue, item]); } }; return ( <Box padding={4}> <Flex width="100%" justifyContent="center"> <IconButton accessibilityControls="sections-dropdown-example" accessibilityExpanded={open} accessibilityHaspopup accessibilityLabel="Create Pin Menu" bgColor="lightGray" icon="add" iconColor="darkGray" onClick={() => setOpen((prevVal) => !prevVal)} ref={anchorRef} selected={open} size="lg" tooltip={{ text: 'Create', accessibilityLabel: '', idealDirection: 'up', }} /> {open && ( <Dropdown anchor={anchorRef.current} id="sections-dropdown-example" onDismiss={() => setOpen(false)} > <Dropdown.Section label="Create"> <Dropdown.Item onSelect={onSelect} option={{ value: 'Pin', label: 'Pin' }} selected={selected} /> <Dropdown.Item onSelect={onSelect} option={{ value: 'Story Pin', label: 'Story Pin' }} selected={selected} /> </Dropdown.Section> <Dropdown.Section label="Add"> <Dropdown.Item badge={{ text: 'New' }} onSelect={onSelect} option={{ value: 'Note', label: 'Note' }} selected={selected} /> </Dropdown.Section> </Dropdown> )} </Flex> </Box> ); }
Writing
When pairing IconButton with Tooltip, refer to the Tooltip component for writing guidelines.
- Use a descriptive label to describe the IconButton action by beginning with a verb.
Use the words "image" or "icon" in the description label; instead, prefer to use verbs that describe the action, e.g. "Save" or "Edit".
Component quality checklist
Quality item | Status | Status description |
---|---|---|
Figma Library | Ready | Component is available in Figma across all platforms. |
Responsive Web | Ready | Component is available in code for web and mobile web. |
iOS | Planned | Component is slotted to be built for iOS. |
Android | Planned | Component is slotted to be built for Android. |
Related
Button
Button allows users to take actions, and make choices using text labels to express what action will occur when the user interacts with it.
Icon
IconButtons use icons instead of text to convey available actions on a screen. Use an existing one from the Gestalt Icon library.
OnLinkNavigationProvider
OnLinkNavigationProvider allows external link navigation control across all children components with link behavior.
Dropdown
It's most common to anchor Dropdown to Button or IconButton.