Button
- Buttons with Icons
- Buttons with Images
- Disabled
- Focus
- Keyboard Usage
- Best Practices
- Related Components
The Button component allows users to perform actions. It comes in several different style variants and supports icons as well as text labels.
Buttons with Icons
Buttons can have icons instead of text, or they can have icons along with text.
Use icons sparingly. Most actions are difficult to represent reliably with icons. The benefit of icons plus text should be weighed against the visual clutter they create.
Icon-only buttons should be used primarily for common recurring actions with highly standardized, universally understood icons (e.g., a cross for close), and for actions that are repeated, such as in lists and tables. They should also include a textual alternative for screen readers using the aria-label attribute (see the first two buttons in the previous example).
Additionally, tooltips can be added to provide a description of the action that the button triggers (see the Close button in the previous example).
Buttons with Images
Images on buttons can be used like icons. See the icon usage recommendations for more information.
Disabled
Buttons representing actions that aren’t currently available to the user should be either hidden or disabled. A disabled button is rendered as "dimmed".
Focus & Hover
By default, disabled buttons are not focusable and cannot react to hover events. This can cause accessibility issues by making them entirely invisible to assistive technologies, and prevents the use of Tooltips to explain why the action is not available. This can be addressed by enabling the feature flag accessibleDisabledButtons, which allows you to focus and hover on disabled buttons, while preventing them from being triggered:
Source code
Flow
Flow# Add this line to src/main/resources/vaadin-featureflags.properties
com.vaadin.experimental.accessibleDisabledButtons=trueLit & React
Lit & ReactAlternatives to Disabling
The most obvious alternative to disabling a button is to hide it. This reduces UI clutter, but can cause confusion since the user won’t know where to watch for the button once the action it represents becomes available. There’s also a risk of undesired layout shifts in the UI when the button appears.
Another option is to keep the button visible and enabled, but show an error, e.g. using a Notification, when it’s clicked. This option is best combined with some custom styling of the button to give the user a hint that the action is unavailable.
Prevent Multiple Clicks Flow
Buttons can be configured to be disabled when clicked. The button is disabled immediately on the client side, so additional clicks don’t reach the server while the action is being processed. This also communicates to the user that the click was received.
In most cases, the button only needs to be disabled while the server handles the click. Use the UNTIL_RESPONSE mode for this. The button is enabled again automatically once the click has been handled, so no additional code is needed in the click listener.
When the action continues after the click listener returns, for example in a background job, use the UNTIL_ENABLED mode instead. The button then stays disabled until the application enables it again:
Source code
Java
Button button = new Button("Generate Report");
button.setDisableOnClick(DisableOnClickMode.UNTIL_ENABLED);
button.addClickListener(event -> {
var ui = UI.getCurrent();
reportService.generateReport()
.thenAccept(ui.accessLater(report -> {
showReport(report);
button.setEnabled(true);
}, null));
});Updating the button from a background thread requires server push.
Focus
As with other components, the focus ring is only rendered when the button is focused by keyboard or programmatically.
Best Practices
Below are some best practice recommendations related to buttons and their labels.
Button Labels
A label should describe the action, preferably using active verbs, such as "View Details" rather than "Details". To avoid ambiguity, also specify the object of the verb, such as "Save Changes" instead of "Save". They also should be brief, ideally less than three words or twenty-five characters.
Button groups representing options, such as the buttons of a Confirm Dialog, should state what each option represents (e.g., "Save Changes"). Don’t label a button "Yes" since that requires the user to read the question being asked. It’ll increase the risk of selecting the wrong option.
Use ellipsis (i.e., …) when an action is not immediate, but requires more steps to complete. This is useful, for example, for destructive actions like "Delete…" when a Confirm Dialog is used to confirm the action before it’s executed.
ARIA Labels
The aria-label attribute can be used to provide a separate label for accessibility technologies (AT), such as screen readers. This is important, for example, for icon-only buttons that lack a visible label.
A button with a regular, visible label can also benefit from a separate aria-label to provide more context that may otherwise be difficult for an AT user to perceive. In the example here, each button’s aria-label specifies which email address is removed:
Buttons in Forms
Buttons in forms should be placed below the form with which they’re associated. They should be aligned left, with the primary action first, followed by other actions, in order of importance.
Buttons in Dialogs
Buttons in dialogs should be placed at the bottom of the dialog and aligned right. Primary action should be last, preceded by other actions. Dangerous actions should be aligned left, to avoid accidental clicks, especially if no confirmation step is included.
Global vs. Selection-Specific Actions
In lists of selectable items — such as in a Grid — that provide actions applicable to the selected item, buttons for selection-specific actions should be placed apart from global actions that aren’t selection-specific. They should be located below the list of selectable items.
In the example below, the global Add User action is separated from the selection-specific actions below the Grid: