Popover

Share this page

Anyone with the link can view the page.

@use 'sprucecss/scss/spruce' as *;

.popover-demo {
  display: flex;
  justify-content: center;
  padding-block: spacer('xl');
}

.popover {
  background-color: color('surface');
  border: config('border-width-base', $display) solid color('border');
  border-radius: radius('lg');
  box-shadow: shadow('xl');
  color: color('text');
  inline-size: min(22rem, calc(100vi - #{spacer('m')}));
  inset: auto;
  margin: 0;
  padding: spacer('m');
  position-area: block-end;
  position-try-fallbacks: flip-block;
  @include layout-stack('s');

  // Fallback without anchor positioning: centered like a small dialog.
  @supports not (position-area: block-end) {
    inset: 0;
    margin: auto;
    max-block-size: max-content;
  }

  &::backdrop {
    background-color: transparent;
  }

  &:popover-open {
    @include motion-safe {
      animation: popover-in 0.15s ease-out;
    }
  }

  &__header {
    align-items: center;
    display: flex;
    gap: spacer('s');
    justify-content: space-between;
  }

  &__title {
    font-size: font-size('h5');
    margin: 0;
  }

  &__text {
    color: color('muted');
    font-size: config('font-size-sm', $typography);
  }

  .form-group--stacked .form-control {
    min-inline-size: 0;
  }
}

@keyframes popover-in {
  from {
    opacity: 0;
    translate: 0 -0.25rem;
  }
}
<div class="popover-demo">
    <button class="btn btn--outline-primary" type="button" popovertarget="popover-share">Share</button>
    <div class="popover" id="popover-share" popover>
        <div class="popover__header">
            <h2 class="popover__title">Share this page</h2>
            <button class="btn btn--ghost-secondary btn--icon btn--sm" type="button" popovertarget="popover-share" popovertargetaction="hide" aria-label="Close"><svg class="btn__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true" focusable="false"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
        </div>
        <div class="form-group--stacked">
            <label class="sr-only" for="popover-share-link">Link</label>
            <input class="form-control form-control--sm" id="popover-share-link" type="text" value="https://sprucecss.com/blocks/" readonly>
            <button class="btn btn--primary btn--sm" type="button" data-copy-target="popover-share-link">Copy</button>
        </div>
        <p class="popover__text">Anyone with the link can view the page.</p>
    </div>
</div>

Popover

On this page

A small floating panel anchored to a button, built on the native Popover API: no JavaScript needed to open, close or dismiss it.

Technical Details

  • popovertarget connects the button and the panel; the browser handles toggling, light dismiss (click outside, Esc) and the top layer, and sets aria-expanded on the button.
  • The panel is positioned under its button with CSS anchor positioning (position-area: block-end, flipping when there is no room). Browsers without anchor positioning show it centered.
  • Unlike a dialog, a popover doesn't trap the focus or make the page inert; use it for small, non-blocking content like share options or quick settings.
  • The copy button works with the script of the Copy Button component.

Documentation

Learn about Spruce CSS through our extensive documentation.

Components

Explore our UI library of accessible components built with Spruce CSS.

Blocks and Pages

Full-width page blocks and complete page templates, ready to copy.

Find us on GitHub

Did you find a bug? Have an idea or a question? Please open an issue to help us develop the project.