# Popover

![Popover overlays with pointers](/files/-LXQcGd-PekMAyECo7PR)

### Introduction

***NOTE**: This pattern was previously known as "flyout".*

Popover is a composite pattern containing an element (typically a button) that *hosts* a non-modal overlay element. The overlay discloses contextually relevant secondary content and/or actions.

Popover forms the basis of the following composite patterns:

* [Comboxbox](/mindpatterns/input/combobox.md)
* [Fake Menu Button](/mindpatterns/navigation/fake-menu-button.md)
* [Infotip Button](/mindpatterns/disclosure/infotip.md)
* [Listbox Button](/mindpatterns/input/listbox-button.md)
* [Menu Button](/mindpatterns/input/menu-button.md)
* [Tooltip](/mindpatterns/disclosure/tooltip.md)
* [Tourtip](/mindpatterns/messaging/tourtip.md)

The pattern discussed here in this document is a more generic use-case, where the popover may contain *any* kind of content.

### Working Examples

You can take a look at a generic popover on our [examples site](http://ebay.github.io/mindpatterns/disclosure/popover/).

### Terminology

* **popover**: the composite pattern as a \*whole\*, containing an overlay and its host
* **host**: the element that *hosts* the overlay
* **overlay**: the non-modal overlay that contains the content related to its host
* **content**: the actual content of the overlay
* **expanded/collapsed**: the overlay state (visible or hidden)

### Best Practices

The overlay can hold any kind of content, but for an overlay that demands user acknowledgement or input, or with additional rich interactions, consider using a [dialog](/mindpatterns/disclosure/lightbox-dialog.md) instead.

The overlay expands or collapses via any combination of the following events:

* **Click** event of host
* **Hover** event of host (discouraged)
* **Focus** event of host (discouraged)
* **System** event at page load or after some arbitrary time

A link **must not** be the host of a click-activated popover. Clicking the host should always navigate to the URL in this case.

Overlay **must** be non-modal (i.e. must not trap keyboard focus or mask page background). For modal behaviour please consider the [dialog](https://github.com/ebay/mindpatterns/tree/6c14ac7802634b97b44038d80935b912adbcd5cf/discolosure/dialog.md) pattern instead.

Overlay **must** be placed directly after the host in DOM. This ensures natural tab order and reading order without JavaScript.

*If* system-activated (e.g. a [Tourtip](/mindpatterns/messaging/tourtip.md)), overlay **must** remain onscreen until explicitly dismissed by the user.

*If* focus-activated, overlay *should* *not* contain long blocks of interactive elements. This measure prevents keyboard users from having to tab through secondary or tertiary content inside of the overlay.

### Interaction Design

This section provides interaction guidelines for keyboard, screen reader, and pointing devices.

#### Keyboard

Tab order **must** flow directly from host into first focusable element inside overlay. If the overlay has no focusable element, tab order flows to next page control instead.

*If* not system-activated, host **must** be keyboard focus-able.

*If* click-activated, popover **must** expand overlay when host receives keyboard click.

*If* focus-activated (discouraged), popover **must** expand when host receives keyboard focus.

*If* focus-activated (discouraged), popover **must** collapse when flyout loses keyboard focus.

#### Screen Reader

Reading order **must** flow directly from host into overlay.

Overlay must not be conveyed as a dialog.

*If* system-activated *and* high-priority, screen reader **must** announce presence and/or content overlay.

#### Mouse

*If* hover-activated (discouraged), popover **must** expand when host receives mouse hover.

*If* hover-activated (discouraged), popover **must** collapse when mouse leaves flyout.

*If* click-activated, popover **must** expand when host receives mouse click.

*If* system-activated, popover **must** collapse when clicking close button.

### Touch

Hover behaviour can be problematic or impossible for touch. You may wish to consider using the [Infotip](/mindpatterns/disclosure/infotip.md) pattern instead.

*If* click-activated, popover **must** expand when host receives tap.

*if* system-activated, popover **must** close when tapping close button.

### Developer Guide

Let's examine a click-activated popovers. Click-activated popovers typically occur with buttons, where clicking the button expands the popover.

The key things to consider are:

1. Server-side rendering or client-side rendering of overlay content (or both)
2. Placement of overlay element in relation to host
3. Using aria-expanded state to toggle CSS display
4. Determining the live-region property

#### Content

Content rendered by the server will be visible by default before & without CSS or JavaScript. If the content is secondary in nature, you may wish to render the content on the client instead.&#x20;

Whatever progressive enhancement strategy you choose, the following structure is the goal:

```markup
<span class="popover popover--click">
    <button class="popover__host" type="button" disabled>Toggle Popover</button>
    <span aria-live="off">
        <div class="popover__overlay">
            <!-- popover content -->
        </div>
    </span>
</span>
```

Notice placement of the host (the button) directly before the overlay element. This allows natural keyboard and reading order from the host into the overlay.

An optional live-region element wraps the overlay. The live-region property may be set to "off", "polite" or "assertive".

#### Presentation

The overlay can be absolute or fixed positioned:

```css
.popover__overlay {
    display: none;
    position: absolute;
    z-index: 1;
}
```

We have hidden the overlay by default (display: none). We use the aria-expanded state of the host to control the display of the overlay:

```css
.popover__host[aria-expanded=true] ~ [aria-live] .popover__overlay {
    display: block;
}
```

#### Behaviour

CSS alone cannot trigger the expanded state, so we require a small amount of Javascript to handle this behaviour:

```javascript
document.querySelector('.popover__host').addEventListener('click', function() {
  const isExpanded = this.getAttribute('aria-expanded') === 'true';

  this.setAttribute('aria-expanded', isExpanded ? 'false' : 'true');
});
```

Clicking the button with mouse, keyboard or touch will now toggle the aria-expanded state of the button.

### ARIA Reference

#### aria-expanded

This boolean attribute signifies the expanded state of the host element.

#### aria-live

If wishing to announce the content of the popover when it expands, set aria live to polite or assertive.&#x20;

### FAQ

#### Didn't this pattern used to be called Flyout?

Yes it did! In most practical senses, the term flyout is synonomous with popover; they are both used to describe transient (i.e. non-modal) overlays of content.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ebay.gitbook.io/mindpatterns/disclosure/popover.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
