Docs

Documentation versions (currently viewingVaadin 24)

Popover

Popover is a generic overlay whose position is anchored to an element in the UI.

A generic overlay whose position is anchored to an element in the UI.

Open in a
new tab
<vaadin-popover
  for="show-notifications"
  theme="arrow no-padding"
  modal
  accessible-name-ref="notifications-heading"
  content-width="300px"
  position="bottom"
  ${popoverRenderer(this.notificationsRenderer, [
    this.unreadNotifications,
    this.allNotifications,
  ])}
></vaadin-popover>

Popovers support focusable, interactive content, and can be used to build virtually any type of anchored overlays from custom drop-down fields and drop-down buttons to and interactive tooltips.

The popover’s position is anchored to an element in the UI, called the target element.

Popovers differ from Dialogs in that they are visually anchored to a target element, and they differ from Tooltips in that they can be focused and support rich, interactive content.

Opening and Closing

Popovers can be configured to open and close based on different pointer and keyboard based triggers. See Typical Use Cases for examples.

Opening Triggers

Three target element triggers can be configured to open the popover:

  • Click: clicking the target element, or pressing Space when the target element has focus (default)

  • Hover: hovering over the target element

  • Focus: focusing the target element

Popover popover = new Popover();
popover.setOpenOnClick(false);
popover.setOpenOnHover(true);
popover.setOpenOnFocus(true);

All three triggers can be enabled simultaneously. If no opening trigger is enabled, the popover can only be opened programmatically.

The hover and focus opening triggers have a configurable opening delay.

Popover popover = new Popover();
popover.setHoverDelay(500);
popover.setFocusDelay(500);

Closing Triggers

The following triggers close the popover by default:

  • Target click: Clicking the target element (non-modal popovers only)

  • Outside click: clicking anywhere outside the overlay (can be disabled)

  • Esc: pressing Esc (can be disabled)

Popover popover = new Popover();
popover.setCloseOnEsc(false);
popover.setCloseOnOutsideClick(false);

Additionally:

  • When opened on hover, the popover closes on mouseout, i.e. when the pointer leaves the target element and the overlay.

  • When opened on focus, the popover closes on blur, i.e. when focus is no longer on the target element or in the overlay.

The mouseout closing trigger has a configurable delay.

Popover popover = new Popover();
popover.setHideDelay(500);

Auto Focus

Keyboard focus can be automatically moved to the Popover when it opens. This is recommended for popovers with interactive content that the user is expected to interact with. Modal popovers have auto-focus behavior by default. Popovers opened with hover or focus should not use auto-focus.

Popover popover = new Popover();
popover.setAutofocus(true);

Positioning

By default, popovers open below their target element, horizontally centered to its midpoint, but the positioning options allow this to be changed to any edge or corner, depending on what is most appropriate for the use case.

The popover’s position is automatically maintained if the target element scrolls within the viewport. If there is insufficient space in the viewport for the desired positioning, the popover automatically shifts to fit within the viewport.

Open in a
new tab
<vaadin-popover
  for="target"
  .position="${this.position}"
  ${popoverRenderer(this.popoverRenderer)}
></vaadin-popover>

Target Gap

The distance between the popover and the target element can be customized by setting the following CSS properties on the Popover component:

  • --vaadin-popover-offset-top

  • --vaadin-popover-offset-bottom

  • --vaadin-popover-offset-start

  • --vaadin-popover-offset-end

Target Arrow

Popovers can render a wedge-shaped arrow tip pointing at the target element.

Open in a
new tab
<vaadin-popover
  for="target"
  theme="arrow"
  ${popoverRenderer(this.popoverRenderer)}
></vaadin-popover>

Configuring Delays

The delay before popover opens can be configured separately for hover and focus. There is no delay before the popover appears on click or when opening programmatically.

The delay before popover closes — when the pointer leaves the target element — can also be configured separately. On blur, though, the popover is closed immediately to avoid confusion when focusing another element.

// Global delay configuration:
Popover.setDefaultFocusDelay(2000);
Popover.setDefaultHoverDelay(1000);
Popover.setDefaultHideDelay(1000);

// Overriding delays for a particular popover:
Popover popover = new Popover();
popover.setHoverDelay(0);

Dimensions

By default, the Popover’s size is determined by its contents, but an explicit width and height can be set on the Popover itself.

Contents that exceed the width of the popover will scroll.

The maximum width of popovers is limited to the width of the viewport, minus a small margin that can be customized with CSS by overriding the inset property of the vaadin-popover-overlay element.

Modality

A modal Popover blocks the user from interacting with the rest of the user interface while open, automatically moves focus from the target element to the Popover, and traps keyboard focus within it.

When combined with an outside click closing trigger, modality prevents accidentally triggering other UI elements when clicking outside the Popover to close it.

By default, modal popovers do not render a modality curtain (or backdrop), but one can be enabled separately. A modality curtain can be useful for de-emphasizing the UI in the background and to give a visual indication that the rest of the UI is blocked from user interaction.

Open in a
new tab
<vaadin-popover
  for="target"
  modal
  with-backdrop
  ${popoverRenderer(this.popoverRenderer)}
></vaadin-popover>

Accessibility

By default, the Popover overlay has the ARIA role dialog. This can be changed to another role to provide appropriate semantics for the type of content and interaction in the popover (see Typical Use Cases for examples).

  • menu: when the content is a list of actions or links

  • listbox: when the content is a list form which you can select one or more items

  • grid: when the content is a tabular structure from which you select an item

  • tree: when the content is a hierarchical list

Remember that, unlike Tooltip, the contents of a Popover are not automatically announced by screen readers when it opens. Consider using a live region to announce non-interactive popovers, and ensure keyboard access to interactive popovers.

The target element is automatically applied aria-controls (with a reference to the Popover overlay), aria-haspopup (with the overlay’s role as the value), and aria-expanded (set to true when open, and to false otherwise).

An accessible name can be provided for the overlay using the ARIA label API:

Popover popover = new Popover();
popover.setAriaLabel("Label");
// OR
popover.setAriaLabelledby("label-element-id");

Typical Use Cases

Here are a few examples of common use cases for the Popover component with recommended configurations.

Open in a
new tab
<vaadin-popover
      for="range-field"
      .trigger="${this.trigger}"
      focus-delay="0"
      modal
      content-width="325px"
      position="bottom-start"
      accessible-name="Select a date range"
      .opened="${this.opened}"
      @opened-changed="${this.onOpenedChanged}"
      ${popoverRenderer(this.popoverRenderer, [this.from, this.to])}
    ></vaadin-popover>
popoverRenderer() {
  return html`
    <vaadin-select
      label="Common ranges"
      .items="${this.presets}"
      placeholder="Select preset"
      style="width: 100%"
      .value="${this.range}"
      @change="${this.onRangeChange}"
    ></vaadin-select>
    <vaadin-horizontal-layout theme="spacing-s" style="align-items: baseline">
      <vaadin-date-picker
        label="From"
        style="width: 150px"
        .value="${this.from}"
        @change="${this.onFromChange}"
      ></vaadin-date-picker>
      <div></div>
      <vaadin-date-picker
        label="To"
        style="width: 150px"
        .value="${this.to}"
        @change="${this.onToChange}"
      ></vaadin-date-picker>
    </vaadin-horizontal-layout>
  `;
}
  • Opens on click, focus

  • Closes on Esc, blur, outside click, target click, and programmatically upon selection

  • Modal, no modality curtain (drop-down fields typically don’t have curtains)

  • Auto-focused

  • ARIA role dialog

  • ARIA label “Select a date range”

User Menu

Open in a
new tab
<vaadin-popover
  for="avatar"
  position="bottom-end"
  modal
  overlay-role="menu"
  accessible-name="User menu"
  theme="no-padding"
  ${popoverRenderer(this.userMenuRenderer, [this.person])}
></vaadin-popover>
  • Opens on click

  • Closes on Esc, outside click, target click

  • Modal, no modality curtain (small popovers like this usually don’t need them)

  • ARIA role menu (the overlay’s content is a menu; although there are non-list elements, they are not interactive, nor do they need to be announced by screen readers)

  • ARIA label “User menu”

Note: if the popover only needs to contain menu items, consider using a Menu Bar or Context Menu instead.

Notification Panel

Open in a
new tab
<vaadin-popover
  for="show-notifications"
  theme="arrow no-padding"
  modal
  accessible-name-ref="notifications-heading"
  content-width="300px"
  position="bottom"
  ${popoverRenderer(this.notificationsRenderer, [
    this.unreadNotifications,
    this.allNotifications,
  ])}
></vaadin-popover>
  • Opens on click

  • Closes on Esc, outside click, target click

  • Modal, no modality curtain (small popovers like this usually don’t need them)

  • ARIA role dialog (although mainly a list, there interactive non-list elements as well)

  • ARIA labelled-by pointing to heading in overlay

  • Arrow variant

Rich, Interactive Tooltip

Open in a
new tab
<vaadin-integer-field id="cvv-field" label="CVV" style="width: 60px"></vaadin-integer-field>
<vaadin-popover
  for="cvv-field"
  .trigger="${this.trigger}"
  position="top"
  theme="arrow"
  accessible-name-ref="cvv-heading"
  ${popoverRenderer(this.cvvRenderer)}
></vaadin-popover>
  • Opens on hover, focus

  • Closes on Esc, outside click (as well as mouseout and blur)

  • Non-modal

  • Not auto-focused

  • ARIA role dialog (tooltip would be invalid due to interactive contents)

  • ARIA labelled-by pointing to heading in overlay

  • Positioned above target

  • Arrow variant

Anchored Modal Dialog

Open in a
new tab
<vaadin-horizontal-layout style="align-items: baseline">
      <h3 style="flex: 1;">Employees</h3>
      <vaadin-button id="toggle-columns" theme="icon" aria-label="Show / hide columns">
        <vaadin-icon icon="vaadin:grid-h"></vaadin-icon>
      </vaadin-button>
    </vaadin-horizontal-layout>

    <vaadin-popover
      for="toggle-columns"
      modal
      with-backdrop
      position="bottom-end"
      ${popoverRenderer(this.popoverRenderer, [this.gridColumns])}
    ></vaadin-popover>
popoverRenderer() {
  const visibleColumns = this.gridColumns
    .filter((column) => column.visible)
    .map((column) => column.key);

  return html`
    <div style="font-weight: 600; padding: var(--lumo-space-xs);">Configure columns</div>
    <vaadin-checkbox-group theme="vertical" .value="${visibleColumns}">
      ${this.gridColumns.map(
        (column) => html`
          <vaadin-checkbox
            .label="${column.label}"
            .value="${column.key}"
            @change="${this.onCheckboxChange}"
          ></vaadin-checkbox>
        `
      )}
    </vaadin-checkbox-group>
    <vaadin-horizontal-layout style="justify-content: space-between;">
      <vaadin-button theme="small" @click="${this.showAllColumns}">Show all</vaadin-button>
      <vaadin-button theme="small" @click="${this.resetColumns}">Reset</vaadin-button>
    </vaadin-horizontal-layout>
  `;
}
  • Opens on click

  • Closes on Esc, outside click

  • Modal, with curtain

  • Auto-focused

  • ARIA role dialog

  • ARIA labelled-by pointing to heading in the overlay

Note: if the dialog doesn’t benefit from being anchored-positioned to another element, consider using a Dialog instead.

Component Usage Recommendation

Dialog

Use instead of Popover if there is no need to visually associate it with another UI element. Modal dialogs are a better option for transactional operations. Modal dialogs provide full-stack modality (e.g. keyboard shortcuts defined in the UI behind are blocked while the Dialog is open)

Tooltip

Use instead of Popover if the content is just text.

Context Menu

Use instead of Popover if the content is a list of actions or toggles.

Menu Bar

Same as Context Menu, but with built-in trigger buttons.