Skip to main content
Components
Popover
pnpm add @winkintel/bootstrap-svelte
GitHub

Popover

Documentation and examples for adding custom Bootstrap popovers with content and positioning.


Interactive Playground

Controls

Preview

Code

            
            <Button id="playground-popover-button" colorVariant="primary"">
  Toggle Popover
</Button>

<Popover.Root
  placement="right"
  trigger="click"
  referenceElementId="playground-popover-button">
  <Popover.Header level={3}>Popover title</Popover.Header>
  <Popover.Body>
    <p>This is a simple popover content. You can customize this in various ways.</p>
  </Popover.Body>
</Popover.Root>


        

The Popover component creates a small overlay that appears when a user clicks, hovers, or focuses on an element. It consists of several components that work together: Popover.Root, Popover.Header, and Popover.Body.

            
            <Button id="basic-popover-button" colorVariant="primary">
    Click for Popover
</Button>

<Popover.Root isShown={isPopoverShown} referenceElementId="basic-popover-button">
    <Popover.Header>Popover Title</Popover.Header>
    <Popover.Body>
        <p>This is the popover body content. It can contain various elements.</p>
    </Popover.Body>
</Popover.Root>
        

Popovers can be triggered in different ways: click, hover, focus, or a combination of them. The default trigger is click.

            
            <!-- Click trigger (default) -->
<Button id="click-popover-button" colorVariant="secondary">
    Click me
</Button>

<Popover.Root referenceElementId="click-popover-button" trigger="click">
    <Popover.Header>Click Triggered</Popover.Header>
    <Popover.Body>
        <p>This popover is activated by clicking on the button.</p>
    </Popover.Body>
</Popover.Root>

<!-- Hover trigger -->
<Button id="hover-popover-button" colorVariant="secondary">
    Hover me
</Button>

<Popover.Root referenceElementId="hover-popover-button" trigger="hover">
    <Popover.Header>Hover Triggered</Popover.Header>
    <Popover.Body>
        <p>This popover is activated by hovering over the button.</p>
    </Popover.Body>
</Popover.Root>

<!-- Focus trigger -->
<Button id="focus-popover-button" colorVariant="secondary">
    Focus me
</Button>

<Popover.Root referenceElementId="focus-popover-button" trigger="focus">
    <Popover.Header>Focus Triggered</Popover.Header>
    <Popover.Body>
        <p>This popover is activated by focusing on the button.</p>
    </Popover.Body>
</Popover.Root>

<!-- Multiple triggers -->
<Button id="multi-trigger-popover-button" colorVariant="secondary">
    Hover or focus me
</Button>

<Popover.Root referenceElementId="multi-trigger-popover-button" trigger="hover focus">
    <Popover.Header>Multiple Triggers</Popover.Header>
    <Popover.Body>
        <p>This popover is triggered by either hovering or focusing.</p>
    </Popover.Body>
</Popover.Root>
        

Popovers can be placed in various positions relative to their reference element: top, right, bottom, left, or auto. The default placement is right.

            
            <!-- Top placement -->
<Button id="top-popover-button" colorVariant="secondary">
    Popover on top
</Button>

<Popover.Root referenceElementId="top-popover-button" placement="top">
    <Popover.Header>Top Placed</Popover.Header>
    <Popover.Body>
        <p>This popover appears at the top.</p>
    </Popover.Body>
</Popover.Root>

<!-- Right placement (default) -->
<Button id="right-popover-button" colorVariant="secondary">
    Popover on right
</Button>

<Popover.Root referenceElementId="right-popover-button" placement="right">
    <Popover.Header>Right Placed</Popover.Header>
    <Popover.Body>
        <p>This popover appears on the right.</p>
    </Popover.Body>
</Popover.Root>

<!-- Bottom placement -->
<Button id="bottom-popover-button" colorVariant="secondary">
    Popover on bottom
</Button>

<Popover.Root referenceElementId="bottom-popover-button" placement="bottom">
    <Popover.Header>Bottom Placed</Popover.Header>
    <Popover.Body>
        <p>This popover appears at the bottom.</p>
    </Popover.Body>
</Popover.Root>

<!-- Left placement -->
<Button id="left-popover-button" colorVariant="secondary">
    Popover on left
</Button>

<Popover.Root referenceElementId="left-popover-button" placement="left">
    <Popover.Header>Left Placed</Popover.Header>
    <Popover.Body>
        <p>This popover appears on the left.</p>
    </Popover.Body>
</Popover.Root>

<!-- Auto placement -->
<Button id="auto-popover-button" colorVariant="secondary">
    Popover with auto placement
</Button>

<Popover.Root referenceElementId="auto-popover-button" placement="auto">
    <Popover.Header>Auto Placed</Popover.Header>
    <Popover.Body>
        <p>This popover uses automatic placement based on available space.</p>
    </Popover.Body>
</Popover.Root>
        

You can make popovers dismissible by adding a close button or other interactive element inside the popover body. Use the onHidden event to update your state when the popover is dismissed.

            
            <Button id="dismissible-popover-button" colorVariant="primary" onclick={() => isDismissiblePopoverShown = true}>
    Click for Dismissible Popover
</Button>

<Popover.Root isShown={isDismissiblePopoverShown} referenceElementId="dismissible-popover-button" onHidden={() => isDismissiblePopoverShown = false}>
    <Popover.Header>Dismissible Popover</Popover.Header>
    <Popover.Body>
        <p>This popover can be closed by clicking the button below.</p>
        <div class="mt-2 d-flex justify-content-end">
            <Button colorVariant="secondary" size="sm" onclick={() => isDismissiblePopoverShown = false}>Close</Button>
        </div>
    </Popover.Body>
</Popover.Root>
        

For popovers that should appear and disappear without a fade animation, set the useFade property to false.

            
            <Button id="no-fade-popover-button" colorVariant="primary" onclick={() => isNoFadePopoverShown = true}>
    Popover without fade
</Button>

<Popover.Root isShown={isNoFadePopoverShown} useFade={false} referenceElementId="no-fade-popover-button" onHidden={() => isNoFadePopoverShown = false}>
    <Popover.Header>No Fade Effect</Popover.Header>
    <Popover.Body>
        <p>This popover appears and disappears without a fade animation.</p>
        <div class="mt-2 d-flex justify-content-end">
            <Button colorVariant="secondary" size="sm" onclick={() => isNoFadePopoverShown = false}>Close</Button>
        </div>
    </Popover.Body>
</Popover.Root>
        

You can customize the header element by changing its level (h1-h6) using the level prop or by adding CSS classes.

            
            <Button id="custom-header-popover-button" colorVariant="secondary">
    Custom Header Level
</Button>

<Popover.Root referenceElementId="custom-header-popover-button">
    <Popover.Header level={1}>H1 Title</Popover.Header>
    <Popover.Body>
        <p>This popover uses an h1 for the header instead of the default h3.</p>
    </Popover.Body>
</Popover.Root>

<!-- With custom styling -->
<Button id="custom-styled-header-popover-button" colorVariant="secondary">
    Custom Styled Header
</Button>

<Popover.Root referenceElementId="custom-styled-header-popover-button">
    <Popover.Header class="text-danger">Red Title</Popover.Header>
    <Popover.Body>
        <p>This popover has a red header.</p>
    </Popover.Body>
</Popover.Root>
        

Popovers can contain rich HTML content, including lists, form elements, or interactive components.

            
            <Button id="html-content-popover-button" colorVariant="primary" onclick={() => isHtmlContentShown = true}>
    Popover with HTML content
</Button>

<Popover.Root isShown={isHtmlContentShown} referenceElementId="html-content-popover-button" onHidden={() => isHtmlContentShown = false}>
    <Popover.Header>Rich Content</Popover.Header>
    <Popover.Body>
        <p>Popovers can contain <strong>rich</strong> <em>HTML</em> content.</p>
        <ul class="mb-0">
            <li>List items</li>
            <li>Form elements</li>
            <li>And more!</li>
        </ul>
        <div class="mt-2 d-flex justify-content-between">
            <Button colorVariant="outline-primary" size="sm">Action</Button>
            <Button colorVariant="outline-secondary" size="sm" onclick={() => isHtmlContentShown = false}>Close</Button>
        </div>
    </Popover.Body>
</Popover.Root>
        

When you need to show a popover on a disabled button, you'll encounter an issue: disabled buttons don't trigger mouse or keyboard events. To work around this, wrap the disabled button in a <span> element with tabindex="0" to make it focusable, then attach the popover to the span instead.

            
            <!-- Using a span wrapper with tabindex to enable popover on disabled button -->
<span id="disabled-button-wrapper" tabindex="0" style="display: inline-block; cursor: not-allowed;">
    <Button disabled>Disabled Button</Button>
</span>

<Popover.Root referenceElementId="disabled-button-wrapper" trigger="hover focus">
    <Popover.Header>Disabled Button Popover</Popover.Header>
    <Popover.Body>
        <p>This popover works with a disabled button by using a span wrapper with tabindex="0".</p>
    </Popover.Body>
</Popover.Root>
        

Popover.Root Props

PropTypeDefaultDescription
classstring-Additional CSS classes to apply to the component
containerstring | HTMLElement | falsefalseSpecifies where to append the popover in the DOM. Default is false (appends to body).
elementRefHTMLElement | nullnullReference to the DOM element
idstringAuto-generatedUnique identifier for the offcanvas
isShownbooleanfalseControls whether the popover is visible.
onHidefunctionCallback to invoke when the popover starts hiding.
onHiddenfunctionCallback to invoke when the popover has been hidden.
onShowfunctionCallback to invoke when the popover starts showing.
onShownfunctionCallback to invoke when the popover has been shown.
placement'top' | 'right' | 'bottom' | 'left' | 'auto''right'Where to position the popover relative to the reference element.
referenceElementIdstringThe ID of the element that the popover should be positioned relative to. It accommodates the id containing a hash or not.
trigger'click' | 'hover' | 'focus' | 'manual''click'How the popover is triggered. Can be space-separated for multiple triggers. The use of 'manual' indicates that the popover will be triggered programmatically via the isShown property.
useFadebooleantrueControls whether the popover uses a fade transition.

Popover.Header Props

PropTypeDefaultDescription
level1 | 2 | 3 | 4 | 5 | 63The heading level to use (h1-h6).

CSS Classes

These classes can be used to customize the popover components:

ClassApplied toDescription
.popoverPopover.RootMain container for the popover.
.popover-headerPopover.HeaderStyles the popover title.
.popover-bodyPopover.BodyStyles the popover content.
.bs-popover-topPopover.RootApplied when the popover is placed at the top.
.bs-popover-endPopover.RootApplied when the popover is placed on the right.
.bs-popover-bottomPopover.RootApplied when the popover is placed at the bottom.
.bs-popover-startPopover.RootApplied when the popover is placed on the left.
.fadePopover.RootApplies fade transition effect.
.showPopover.RootMakes the popover visible.