# Dismissible

> Wrap anything with a close button, with an optional auto-dismiss timeout.

URL: https://apogee.avaui.dev/docs/dismissible
Last updated: 2026-10-15

Wrap anything with a close button, with an optional auto-dismiss timeout.

Last updated October 15, 2026

Uses JavaScript

A document-level click listener handles every close button: it dispatches a cancelable `apogee:dismiss` event on the wrapper and, unless you cancel it, removes the element. An island arms the `timeout`.

**Without JS:** The close button is hidden and the content stays put; a timeout never fires.

```astro
<Dismissible>
<Alert color="positive" title="Saved">Your changes are live.</Alert>
</Dismissible>
```

## Add

```sh
npx @ava-ui/apogee add dismissible
```

Depends on `utils`.

## Usage

```astro
---
import Dismissible from '@/components/apogee/Dismissible/Dismissible.astro'
---
<Dismissible timeout={8000} closeLabel="Hide banner">
  <div class="rounded-lg bg-primary-faded p-4 pe-10">Try the new editor.</div>
</Dismissible>

<script>
  document.addEventListener('apogee:dismiss', (e) => {
    // e.preventDefault() keeps the element; otherwise it is removed.
    localStorage.setItem('banner-dismissed', '1')
  })
</script>
```

Leave room for the button at the end edge of your content (`pe-10`).

## API

`@composable`. Any other native attribute passes through to the wrapper.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `timeout` | `number` | — | Auto-dismiss after this many milliseconds. |
| `closeLabel` | `string` | `'Dismiss'` | Accessible name of the close button. |
| `align` | `'top' \| 'center'` | `'top'` | Where the close button sits on the end edge. |
| `variant` | `'default' \| 'media'` | `'default'` | `media` gives the button an opaque pill for use over images. |
| `hideClose` | `boolean` | `false` | No close button; `timeout` and your own `apogee:dismiss` still work. |
| `class` | `string` | — | Extra classes on the wrapper, merged last. |

## Variants

```astro
<Dismissible>…</Dismissible>
<Dismissible timeout={5000}>…</Dismissible>
```

## Align, media and hideClose

```astro
<Dismissible align="center">…</Dismissible>
<Dismissible variant="media"><img … /></Dismissible>
<Dismissible hideClose timeout={8000}>…</Dismissible>
```

## States

-   **Open** — the content shows with a close button (hidden without JS).
-   **Dismissed** — the close button, a `timeout`, or your own `apogee:dismiss` event removes the element. Call `preventDefault()` on the event to keep it.

## Examples

Your own close button: `hideClose`, then any element with `data-dismiss` inside closes it (hide it without JS with `no-js:hidden`). [Banner](https://apogee.avaui.dev/docs/sections/banner) does this to place the button in its layout:

```astro
<Dismissible hideClose class="flex items-center justify-between gap-3 rounded-lg border border-neutral p-3">
<span class="text-sm">Close me from my own button.</span>
<CloseButton data-dismiss label="Dismiss" size="small" class="no-js:hidden" />
</Dismissible>
```

A promo image the user can close. `variant="media"` gives the button an opaque pill so it reads on any photo:

```astro
<Dismissible variant="media" closeLabel="Hide promotion" class="max-w-sm overflow-hidden rounded-lg">
<Image src={placeholder} alt="Autumn sale, 20% off" width={384} height={216} />
</Dismissible>
```

## Accessibility

-   The close button is a real `<button>` with an `aria-label`; set `closeLabel` to name what is being closed.
-   A timed dismissal removes content without user action. Keep timeouts for non-essential messages, and never for errors.
-   Focus is not moved on dismiss; if the button had focus, the browser returns it to the body. Manage it yourself in the `apogee:dismiss` handler when that matters.

## Tokens

| Token | Used for |
| --- | --- |
| `--foreground-neutral-faded` / `--foreground-neutral` | Button icon default / hover |
| `--background-neutral-faded-highlighted` | Button hover fill |
| `--outline-color-focus` | Focus outline |

## Do / Don’t

-   **Do** persist the dismissal when the content is a banner the user should not see again.
-   **Don’t** put a form inside a timed Dismissible.

## Content

-   Set `closeLabel` to say what closes (“Close cookie notice”) when there are several on a page.
-   Keep timed content short enough to read before it leaves: about one sentence per five seconds.

## Related

[

AlertAn inline message with a status color and icon — info, success, warning, or critical; inline, filled or as a full-width banner.

](https://apogee.avaui.dev/docs/alert)[

ToastA transient notification, fired imperatively from anywhere on the page.

](https://apogee.avaui.dev/docs/toast)[

EmptyStateA centered placeholder for empty views — no results, first run, a cleared list.

](https://apogee.avaui.dev/docs/empty-state)
