> Markdown version of [Button](https://vaadin.com/docs/v23/components/button). Section index: [llms.txt](https://vaadin.com/docs/v23/components/llms.txt)

# Button

The Button component allows users to perform actions. It comes in several different style variants, and supports icons as well as text labels.

**TypeScript** — `button-basic.ts`

```html
<vaadin-horizontal-layout theme="spacing" style="align-items: baseline">
  <vaadin-button @click="${() => this.counter++}">Button</vaadin-button>
  <p>Clicked ${this.counter} times</p>
</vaadin-horizontal-layout>
```

**Java** — `ButtonBasic.java`

```java
Button button = new Button("Button");
Paragraph info = new Paragraph(infoText());
button.addClickListener(clickEvent -> {
    counter += 1;
    info.setText(infoText());
});
```

## <a id="styles"></a>Styles

The following variants can be used to distinguish between actions of different importance in the UI:

**TypeScript** — `button-styles.ts`

```html
<vaadin-button theme="primary">Primary</vaadin-button>
<vaadin-button theme="secondary">Secondary</vaadin-button>
<vaadin-button theme="tertiary">Tertiary</vaadin-button>
```

**Java** — `ButtonStyles.java`

```java
Button primaryButton = new Button("Primary");
primaryButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);

Button secondaryButton = new Button("Secondary");

Button tertiaryButton = new Button("Tertiary");
tertiaryButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
```

| Variant   | Usage recommendations                                                                                                                                                                                     |
| --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Primary   | • The most important action in a view or part of a view. • The main closure or continuation action (such as, **Save**) in a form or dialog. • Avoid presenting the user with more than one at any time.   |
| Secondary | • Default style recommended for most actions. • Alternate or negative closure actions (such as, **Cancel**) in a form or dialog.                                                                          |
| Tertiary  | • Lower-importance actions. • Especially in parts of the UI with less space, such as cards, or repeated actions for items in lists, tables, etc. • Caution: this can be mistaken for non-interactive text |

### <a id="danger-error-variants"></a>Danger / Error Variants

A style for distinguishing actions related to dangers, warnings, or errors.

**TypeScript** — `button-error.ts`

```html
<vaadin-button theme="primary error">Primary</vaadin-button>
<vaadin-button theme="secondary error">Secondary</vaadin-button>
<vaadin-button theme="tertiary error">Tertiary</vaadin-button>
```

**Java** — `ButtonError.java`

```java
Button primaryButton = new Button("Primary");
primaryButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY,
        ButtonVariant.LUMO_ERROR);

Button secondaryButton = new Button("Secondary");
secondaryButton.addThemeVariants(ButtonVariant.LUMO_ERROR);

Button tertiaryButton = new Button("Tertiary");
tertiaryButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY,
        ButtonVariant.LUMO_ERROR);
```

Use this style for:

- Dangerous actions, such as those that lose or destroy data.

- Primary danger buttons should only be used when the dangerous action is the most likely action, such as the affirmative **Delete** action in a deletion confirmation dialog.

- Secondary and Tertiary variants can also be used for actions related to current errors, such as resolving them or viewing their details.

### <a id="size-variants"></a>Size Variants

The following size variants are available for Button instances whose size needs to be different from the default:

**TypeScript** — `button-sizes.ts`

```html
<vaadin-button theme="large">Large</vaadin-button>
<vaadin-button theme="normal">Normal</vaadin-button>
<vaadin-button theme="small">Small</vaadin-button>
```

**Java** — `ButtonSizes.java`

```java
Button largeButton = new Button("Large");
largeButton.addThemeVariants(ButtonVariant.LUMO_LARGE);

Button normalButton = new Button("Normal");

Button smallButton = new Button("Small");
smallButton.addThemeVariants(ButtonVariant.LUMO_SMALL);
```

| Variant | Usage recommendations                                                                       |
| ------- | ------------------------------------------------------------------------------------------- |
| Large   | For important call-to-action buttons, where more emphasis is needed.                        |
| Normal  | Default size.                                                                               |
| Small   | Compact option for cramped parts of the UI, if a Tertiary variant isn’t deemed appropriate. |

> **Tip: Default button size can be customized**
>
> Size variants should only be used in special cases. See [Size and Space](https://vaadin.com/docs/v23/styling/lumo/design-tokens/size-space.md#size-and-space) for details on how to change the default button size.

### <a id="miscellaneous-style-variants"></a>Miscellaneous Style Variants

The **Tertiary Inline** variant omits all white space around the label. This can be useful for embedding a Button as part of text content or another component. It shouldn’t be confused with a Link, however.

**TypeScript** — `button-tertiary-inline.ts`

```html
<vaadin-button theme="tertiary-inline">Tertiary inline</vaadin-button>
```

**Java** — `ButtonTertiaryInline.java`

```java
Button tertiaryInlineButton = new Button("Tertiary inline");
tertiaryInlineButton
        .addThemeVariants(ButtonVariant.LUMO_TERTIARY_INLINE);
```

The **Success** and **Contrast** variants should provide additional color options for buttons.

**TypeScript** — `button-success.ts`

```html
<vaadin-button theme="primary success">Primary</vaadin-button>
<vaadin-button theme="secondary success">Secondary</vaadin-button>
<vaadin-button theme="tertiary success">Tertiary</vaadin-button>
```

**Java** — `ButtonSuccess.java`

```java
Button primaryButton = new Button("Primary");
primaryButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY,
        ButtonVariant.LUMO_SUCCESS);

Button secondaryButton = new Button("Secondary");
secondaryButton.addThemeVariants(ButtonVariant.LUMO_SUCCESS);

Button tertiaryButton = new Button("Tertiary");
tertiaryButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY,
        ButtonVariant.LUMO_SUCCESS);
```

**TypeScript** — `button-contrast.ts`

```html
<vaadin-button theme="primary contrast">Primary</vaadin-button>
<vaadin-button theme="secondary contrast">Secondary</vaadin-button>
<vaadin-button theme="tertiary contrast">Tertiary (avoid)</vaadin-button>
```

**Java** — `ButtonContrast.java`

```java
Button primaryButton = new Button("Primary");
primaryButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY,
        ButtonVariant.LUMO_CONTRAST);

Button secondaryButton = new Button("Secondary");
secondaryButton.addThemeVariants(ButtonVariant.LUMO_CONTRAST);

Button tertiaryButton = new Button("Tertiary (avoid)");
tertiaryButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY,
        ButtonVariant.LUMO_CONTRAST);
```

The **Tertiary + Contrast** combination should be avoided because of its similarity to non-interactive text elements.

> **Tip: Default button colors can be customized**
>
> The standard Button colors can be adjusted using [theme features](https://vaadin.com/docs/v23/styling/lumo/design-tokens/color.md). Therefore, these variants shouldn’t be used to replace standard buttons only to achieve a different color.

## <a id="buttons-with-icons"></a>Buttons with Icons

Buttons can have icons instead of text, or on either side of the text:

**TypeScript** — `button-icons.ts`

```html
<!-- Icon button using an aria-label to provide a textual alternative 
     to screen readers -->
<vaadin-button theme="icon" aria-label="Add item">
  <vaadin-icon icon="vaadin:plus"></vaadin-icon>
</vaadin-button>

<!-- Icon button using a tooltip to provide a textual description of 
     the action that it triggers -->
<vaadin-button theme="icon" aria-label="Close">
  <vaadin-icon icon="vaadin:close-small"></vaadin-icon>
  <vaadin-tooltip slot="tooltip" text="Close the dialog"></vaadin-tooltip>
</vaadin-button>

<vaadin-button>
  <vaadin-icon icon="vaadin:arrow-left" slot="prefix"></vaadin-icon>
  Left
</vaadin-button>

<vaadin-button>
  Right
  <vaadin-icon icon="vaadin:arrow-right" slot="suffix"></vaadin-icon>
</vaadin-button>
```

**Java** — `ButtonIcons.java`

```java
// Icon button using an aria-label to provide a textual alternative
// to screen readers
Button plusButton = new Button(new Icon(VaadinIcon.PLUS));
plusButton.addThemeVariants(ButtonVariant.LUMO_ICON);
plusButton.getElement().setAttribute("aria-label", "Add item");

// Icon button using a tooltip to provide textual description
// of the action that it triggers
Button closeButton = new Button(new Icon(VaadinIcon.CLOSE_SMALL));
closeButton.addThemeVariants(ButtonVariant.LUMO_ICON);
closeButton.getElement().setAttribute("aria-label", "Close");
closeButton.setTooltipText("Close the dialog");

Button arrowLeftButton = new Button("Left",
        new Icon(VaadinIcon.ARROW_LEFT));

Button arrowRightButton = new Button("Right",
        new Icon(VaadinIcon.ARROW_RIGHT));
arrowRightButton.setIconAfterText(true);
```

Usage recommendations:

- **Use icons sparingly**. Most actions are difficult to represent reliably with icons, and the benefit of icons plus text should be weighed against the visual clutter this creates.

- **Icon-only** buttons should be primarily used for common recurring actions with highly standardized, universally understood icons, such as, a cross for **close**, and for actions that are repeated, such as in lists and tables.

- Icon-only buttons should provide a textual alternative for screen readers using the `aria-label` attribute. See the first two buttons in the demo above for an example.

- Additionally [tooltips](https://vaadin.com/docs/v23/components/tooltip.md) (since V23.3) can be added to provide a description of the action that the button triggers. See the **Close** button in the demo above for an example.

> **Note: Icon-only button style variant**
>
> Use the `icon` / `LUMO_ICON` theme variant on icon-only buttons to reduce the white space on either side of the icon. The Flow `Button` component automatically applies the `icon` variant if the icon is the only child of the component.

## <a id="buttons-with-images"></a>Buttons with Images

Images can be used similarly to icons. See icon usage recommendations.

**TypeScript** — `button-images.ts`

```html
<vaadin-button theme="icon">
  <img src="${img}" width="100" alt="Vaadin logo" />
</vaadin-button>
```

**Java** — `ButtonImages.java`

```java
Image img = new Image(src, "Vaadin logo");
img.setWidth("100px");

Button imgButton = new Button(img);
imgButton.addThemeVariants(ButtonVariant.LUMO_ICON);
```

## <a id="disabled"></a>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", and is excluded from the focus order. This may be useful when you don’t want interactive UI elements to receive the focus using the tab key.

**TypeScript** — `button-disabled.ts`

```html
<vaadin-button theme="primary" disabled>Primary</vaadin-button>
<vaadin-button theme="secondary" disabled>Secondary</vaadin-button>
<vaadin-button theme="tertiary" disabled>Tertiary</vaadin-button>
```

**Java** — `ButtonDisabled.java`

```java
Button primaryButton = new Button("Primary");
primaryButton.setEnabled(false);
primaryButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);

Button secondaryButton = new Button("Secondary");
secondaryButton.setEnabled(false);

Button tertiaryButton = new Button("Tertiary");
tertiaryButton.setEnabled(false);
tertiaryButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
```

### <a id="hidden-vs-disabled"></a>Hidden vs Disabled

Hiding an unavailable action entirely is often preferable to a disabled button, as this reduces UI clutter. However, in certain situations this can be problematic:

- If the user expects a button to be present, such as at the end of a form, hiding the button can cause confusion, even if the form clearly shows the presence of one or more invalid fields.

- As a hidden button doesn’t occupy any space in the UI, toggling its visibility can cause unwanted changes in the layout of other elements.

### <a id="showing-an-error-on-click"></a>Showing an Error on Click

As an alternative to hiding or disabling buttons, unavailable actions can instead be configured to show an error message when the button is clicked by using a [Notification](https://vaadin.com/docs/v23/components/notification.md) or an adjacent inline text element. This approach is the most accessible option, but may be frustrating to users who expect unavailable actions to be distinguished somehow from available actions.

### <a id="prevent-multiple-clicks"></a>Prevent Multiple Clicks

Buttons can be configured to become disabled automatically when clicked.

This can be useful especially for actions that take a bit longer to perform. Not only does this avoid the need for special handling of clicks while the action is in progress, but it also communicates to the user that the action was received successfully and is being processed.

**TypeScript** — `button-disable-long-action.ts`

```html
<vaadin-horizontal-layout theme="spacing" style="align-items: center;">
  <vaadin-button
    ?disabled=${this.isDisabled}
    @click=${() => {
      this.isDisabled = true;
      this.fakeProgressBar.simulateProgress();
    }}
    style="flex: none;"
    >Perform Action</vaadin-button
  >
  <fake-progress-bar
    @progress-end=${() => {
      this.isDisabled = false;
    }}
  ></fake-progress-bar>
</vaadin-horizontal-layout>
```

**Java** — `ButtonDisableLongAction.java`

```java
Button button = new Button("Perform Action");
FakeProgressBar progressBar = new FakeProgressBar();
button.setDisableOnClick(true);
button.addClickListener(event -> progressBar.simulateProgress());

progressBar.addProgressEndListener(event -> {
    button.setEnabled(true);
});
```

## <a id="focus"></a>Focus

Similar to [input fields](https://vaadin.com/docs/v23/components/input-fields.md), the focus ring is only rendered when the button is focused by keyboard or programmatically.

**TypeScript** — `button-focus.ts`

```html
<vaadin-button focus-ring>Keyboard focus</vaadin-button>
```

### <a id="auto-focus"></a>Auto Focus

Buttons can receive keyboard focus automatically when the UI in which they appear is rendered.

**TypeScript**

```html
<vaadin-button autofocus>Button</vaadin-button>
```

**Java**

```java
Button button = new Button("Button");
button.setAutofocus(true);
```

## <a id="keyboard-usage"></a>Keyboard Usage

A focused button can be triggered with `Enter` or `Space`.

## <a id="best-practices"></a>Best Practices

### <a id="button-labels"></a>Button Labels

- The label should describe the action, preferably using active verbs, such as *"View Details"* rather than *"Details"*.

- In cases of possible ambiguity, also specify the object of the verb, such as *"Save Changes"* instead of *"Save"*.

- Button groups representing options, such as the buttons of a [Confirm Dialog](https://vaadin.com/docs/v23/components/confirm-dialog.md), should state what each option represents, such as *"Save Changes"*, instead of *"Yes"*, as the latter requires the user to read the question being asked, and increases the risk of selecting the wrong option.

- Keep labels short, ideally less than three words or 25 characters.

- Use ellipsis (…) 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](https://vaadin.com/docs/v23/components/confirm-dialog.md) is used to confirm the action before it’s executed.

### <a id="aria-labels"></a>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.

Buttons with regular, visible labels can also benefit from separate `aria-label` to provide more context that may otherwise be difficult for the AT user to perceive. In the example below, the buttons' `aria-label` specifies which email address is removed:

**TypeScript** — `button-labels.ts`

```html
<vaadin-vertical-layout>
  <vaadin-horizontal-layout theme="spacing">
    <vaadin-email-field
      id="primary-email"
      label="Primary email address"
      .value="${this.primaryEmail}"
      @value-changed="${(event: EmailFieldValueChangedEvent) => {
        this.primaryEmail = event.detail.value;
      }}"
    ></vaadin-email-field>
    <vaadin-button
      arial-label="Remove primary email address"
      @click="${() => {
        this.primaryEmail = '';
      }}"
    >
      Remove
    </vaadin-button>
  </vaadin-horizontal-layout>

  <vaadin-horizontal-layout theme="spacing">
    <vaadin-email-field
      id="secondary-email"
      label="Secondary email address"
      .value="${this.secondaryEmail}"
      @value-changed="${(event: EmailFieldValueChangedEvent) => {
        this.secondaryEmail = event.detail.value;
      }}"
    ></vaadin-email-field>
    <vaadin-button
      arial-label="Remove secondary email address"
      @click="${() => {
        this.secondaryEmail = '';
      }}"
    >
      Remove
    </vaadin-button>
  </vaadin-horizontal-layout>
</vaadin-vertical-layout>
```

**Java** — `ButtonLabels.java`

```java
Button clearPrimaryEmail = new Button("Remove", event -> {
    emailField.setValue("");
});
clearPrimaryEmail.getElement().setAttribute("aria-label",
        "Remove primary email address");

Button clearSecondaryEmail = new Button("Remove", event -> {
    secondaryEmailField.setValue("");
});
clearSecondaryEmail.getElement().setAttribute("aria-label",
        "Remove secondary email address");
```

### <a id="buttons-in-forms"></a>Buttons in Forms

**TypeScript** — `button-form.ts`

```html
<vaadin-vertical-layout theme="spacing">
  <vaadin-form-layout .responsiveSteps="${[{ columns: 2 }]}">
    <vaadin-text-field label="First name" value="John"></vaadin-text-field>
    <vaadin-text-field label="Last name" value="Smith"></vaadin-text-field>
    <vaadin-email-field
      label="Email address"
      value="john.smith@example.com"
      colspan="2"
    ></vaadin-email-field>
  </vaadin-form-layout>

  <vaadin-horizontal-layout theme="spacing">
    <vaadin-button theme="primary">Create account</vaadin-button>
    <vaadin-button theme="secondary">Cancel</vaadin-button>
  </vaadin-horizontal-layout>
</vaadin-vertical-layout>
```

**Java** — `ButtonForm.java`

```java
TextField firstNameField = new TextField("First name", "John", "");
TextField lastNameField = new TextField("Last name", "Smith", "");
EmailField emailField = new EmailField("Email address");
emailField.setValue("john.smith@example.com");
FormLayout formLayout = new FormLayout(firstNameField, lastNameField,
        emailField);
formLayout.setResponsiveSteps(new ResponsiveStep("0", 2));
formLayout.setColspan(emailField, 2);

Button createAccount = new Button("Create account");
createAccount.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
Button cancel = new Button("Cancel");

HorizontalLayout buttonLayout = new HorizontalLayout(createAccount,
        cancel);
```

- Buttons should be placed below the form with which they are associated.

- Buttons should be aligned left.

- Primary action should be first, followed by other actions, in order of importance.

### <a id="buttons-in-dialogs"></a>Buttons in Dialogs

**TypeScript** — `button-dialog.ts`

```html
<vaadin-vertical-layout theme="spacing" style="align-items: stretch;">
  <vaadin-form-layout .responsiveSteps="${[{ columns: 2 }]}">
    <vaadin-text-field label="First name" value="John"></vaadin-text-field>
    <vaadin-text-field label="Last name" value="Smith"></vaadin-text-field>
    <vaadin-email-field
      label="Email address"
      value="john.smith@example.com"
      colspan="2"
    ></vaadin-email-field>
  </vaadin-form-layout>

  <vaadin-horizontal-layout
    theme="spacing"
    style="flex-wrap: wrap; justify-content: flex-end;"
  >
    <vaadin-button theme="secondary error" style="margin-inline-end: auto;">
      Delete
    </vaadin-button>
    <vaadin-button theme="secondary">Cancel</vaadin-button>
    <vaadin-button theme="primary">Create account</vaadin-button>
  </vaadin-horizontal-layout>
</vaadin-vertical-layout>
```

**Java** — `ButtonDialog.java`

```java
TextField firstNameField = new TextField("First name", "John", "");
TextField lastNameField = new TextField("Last name", "Smith", "");
EmailField emailField = new EmailField("Email address");
emailField.setValue("john.smith@example.com");
FormLayout formLayout = new FormLayout(firstNameField, lastNameField,
        emailField);
formLayout.setResponsiveSteps(new FormLayout.ResponsiveStep("0", 2));
formLayout.setColspan(emailField, 2);

Button delete = new Button("Delete");
delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
delete.getStyle().set("margin-inline-end", "auto");

Button cancel = new Button("Cancel");

Button createAccount = new Button("Create account");
createAccount.addThemeVariants(ButtonVariant.LUMO_PRIMARY);

HorizontalLayout buttonLayout = new HorizontalLayout(delete, cancel,
        createAccount);
buttonLayout.getStyle().set("flex-wrap", "wrap");
buttonLayout.setJustifyContentMode(JustifyContentMode.END);
```

- Buttons should be placed at the bottom of the dialog.

- Buttons should be 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.

### <a id="global-vs-selection-specific-actions"></a>Global vs. Selection-Specific Actions

In lists of selectable items — such as in a [Grid](https://vaadin.com/docs/v23/components/grid.md) — that provide actions applicable to the selected item, buttons for selection-specific actions should be placed apart from global, non-selection-specific actions. They should be located preferably 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:

**TypeScript** — `button-grid.ts`

```html
<vaadin-vertical-layout theme="spacing" style="align-items: stretch;">
  <vaadin-horizontal-layout style="align-items: center;">
    <h2 style="margin: 0 auto 0 0;">Users</h2>
    <vaadin-button>Add user</vaadin-button>
  </vaadin-horizontal-layout>

  <vaadin-grid
    .items="${this.items}"
    @selected-items-changed="${(event: GridSelectedItemsChangedEvent<Person>) => {
      this.selectedItems = event.target ? [...event.detail.value] : this.selectedItems;
    }}"
  >
    <vaadin-grid-selection-column
      auto-select
      @select-all-changed="${(event: GridSelectionColumnSelectAllChangedEvent) => {
        this.selectedItems = event.detail.value ? this.items : this.selectedItems;
      }}"
    ></vaadin-grid-selection-column>
    <vaadin-grid-column path="firstName"></vaadin-grid-column>
    <vaadin-grid-column path="lastName"></vaadin-grid-column>
    <vaadin-grid-column path="email"></vaadin-grid-column>
  </vaadin-grid>

  <vaadin-horizontal-layout theme="spacing" style="flex-wrap: wrap;">
    <vaadin-button ?disabled="${this.selectedItems.length !== 1}">Edit profile</vaadin-button>
    <vaadin-button ?disabled="${this.selectedItems.length !== 1}">
      Manage permissions
    </vaadin-button>
    <vaadin-button ?disabled="${this.selectedItems.length !== 1}">
      Reset password
    </vaadin-button>
    <vaadin-button
      theme="error"
      ?disabled="${this.selectedItems.length === 0}"
      style="margin-inline-start: auto;"
    >
      Delete
    </vaadin-button>
  </vaadin-horizontal-layout>
</vaadin-vertical-layout>
```

**Java** — `ButtonGrid.java`

```java
H2 users = new H2("Users");
users.getStyle().set("margin", "0 auto 0 0");
Button addUser = new Button("Add user");
HorizontalLayout header = new HorizontalLayout(users, addUser);
header.setAlignItems(Alignment.CENTER);
header.getThemeList().clear();

Button editProfile = new Button("Edit profile");
editProfile.setEnabled(false);

Button managePermissions = new Button("Manage permissions");
managePermissions.setEnabled(false);

Button resetPassword = new Button("Reset password");
resetPassword.setEnabled(false);

Button delete = new Button("Delete");
delete.setEnabled(false);
delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
delete.getStyle().set("margin-inline-start", "auto");

Grid<Person> grid = new Grid<>(Person.class, false);
grid.setSelectionMode(Grid.SelectionMode.MULTI);
grid.addColumn(Person::getFirstName).setHeader("First name");
grid.addColumn(Person::getLastName).setHeader("Last name");
grid.addColumn(Person::getEmail).setHeader("Email");
grid.addSelectionListener(selection -> {
    int size = selection.getAllSelectedItems().size();
    boolean isSingleSelection = size == 1;
    editProfile.setEnabled(isSingleSelection);
    managePermissions.setEnabled(isSingleSelection);
    resetPassword.setEnabled(isSingleSelection);

    delete.setEnabled(size != 0);
});

HorizontalLayout footer = new HorizontalLayout(editProfile,
        managePermissions, resetPassword, delete);
footer.getStyle().set("flex-wrap", "wrap");
```

## <a id="related-components"></a>Related Components

| Component                                                      | Usage recommendations                                                                                                                |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| Anchor                                                         | Use anchor elements instead of buttons for navigation links.                                                                         |
| [Menu Bar](https://vaadin.com/docs/v23/components/menu-bar.md) | Overlay menus with items that trigger actions. Can also be used for single "menu buttons" and "button groups" without overlay menus. |

`8E1BE28B-D5F0-490C-A8FA-82975D9A3B43`
