Skip to content
Ringobook v3.27.0

Popover

Popovers display transient content next to a trigger. Styles are pure HTML + CSS — toggle .show on .ro-popover in your JavaScript to open and close the panel.

Wrap a trigger and a .ro-popover panel inside a container. Previews show the open state with .show and display: block (.show alone sets --is-popover-shown but does not override the base display: none).

<div class="ro-popover-wrapper">
<button class="ro-btn ro-color-scheme-product ro-popover-toggle" type="button">Open</button>
<div class="ro-popover show" style="display: block;">
<div class="ro-popover-body">
<p>A simple message with no header or footer — quick context next to the trigger.</p>
</div>
</div>
</div>
Preview

A simple message with no header or footer — quick context next to the trigger.

Default uses width: max-content (no size marker). md → 300px, lg → 500px — set with .ro-size-md / .ro-size-lg or data-ro-size="md|lg", which updates --ro-popover-width.

<div class="ro-popover show" style="display: block;">
<div class="ro-popover-header">
<h4 class="ro-heading ro-size-4">Popover title</h4>
</div>
<div class="ro-popover-body">
<p>Default — width fits content.</p>
</div>
</div>
<div class="ro-popover ro-size-md show" style="display: block;">
<div class="ro-popover-header">
<h4 class="ro-heading ro-size-4">Popover title</h4>
</div>
<div class="ro-popover-body">
<p>md (300px)</p>
</div>
</div>
<div class="ro-popover ro-size-lg show" style="display: block;">
<div class="ro-popover-header">
<h4 class="ro-heading ro-size-4">Popover title</h4>
</div>
<div class="ro-popover-body">
<p>lg (500px)</p>
</div>
</div>
Preview

Popover title

Default — width fits content.

Popover title

md (300px)

Popover title

lg (500px)

When content exceeds the panel height, .ro-popover-body scrolls inside the panel.

<div class="ro-popover ro-size-lg show" style="height: 300px; display: block;">
<div class="ro-popover-body">
<p>When there is a lot to read, the panel scrolls inside itself...</p>
<!-- additional paragraphs -->
</div>
</div>
Preview

When there is a lot to read, the panel scrolls inside itself so you never lose the page behind it.

Wider layouts are handy for checklists, short forms, or a few paragraphs of help text.

If the window is small, the panel tries to stay fully on screen so nothing gets cut off.

You can mix headings, bullets, or inputs here — same comfortable spacing as the rest of the app.

Section 1 — scroll inside the panel to read everything; the page underneath stays put.

Section 2 — scroll inside the panel to read everything; the page underneath stays put.

Section 3 — scroll inside the panel to read everything; the page underneath stays put.

Section 4 — scroll inside the panel to read everything; the page underneath stays put.

Section 5 — scroll inside the panel to read everything; the page underneath stays put.

Section 6 — scroll inside the panel to read everything; the page underneath stays put.

Use .ro-popover-header, .ro-popover-body, and .ro-popover-footer. The trigger icon weight increases when the adjacent panel has .show (via .ro-popover-toggle:has(+ .ro-popover.show)).

<div class="ro-popover-wrapper">
<button class="ro-btn ro-color-scheme-product ro-popover-toggle" type="button">Full chrome</button>
<div class="ro-popover ro-size-md show" style="display: block;">
<div class="ro-popover-header">
<h4>Your preferences</h4>
<button class="ro-popover-close ro-btn ro-variant-ghost ro-size-sm ro-color-scheme-inverted" type="button" aria-label="Close">
<i class="ro-icon ro-icon-x-small"></i>
</button>
</div>
<div class="ro-popover-body">
<p>Adjust what you need, then save or cancel — you can always open this again later.</p>
</div>
<div class="ro-popover-footer">
<button type="button" class="ro-btn ro-size-sm ro-color-scheme-product ro-u-ml-auto">
<span class="ro-btn-text">Save</span>
</button>
<button type="button" class="ro-btn ro-size-sm ro-color-scheme-product ro-variant-ghost">
<span class="ro-btn-text">Cancel</span>
</button>
</div>
</div>
</div>
Preview

Your preferences

Adjust what you need, then save or cancel — you can always open this again later.

Toggle .show on .ro-popover to open and close the panel:

StateClass / variableEffect
Closed(no .show)display: none, --is-popover-shown: 0, translated down + faded
Open.show + display: block on .ro-popover--is-popover-shown: 1, fade + slide in

When open, set left / top on the panel (position: fixed is applied by default). Remove .show on outside click or when the close button is pressed.

const wrapper = document.querySelector('.ro-popover-wrapper');
const trigger = wrapper.querySelector('.ro-popover-toggle');
const panel = wrapper.querySelector('.ro-popover');
function openPopover() {
panel.classList.add('show'); // sets --is-popover-shown: 1
panel.style.display = 'block'; // required — .show alone does not override display: none
// Position with left/top (Floating UI recommended)
}
function closePopover() {
panel.classList.remove('show'); // --is-popover-shown falls back to 0
panel.style.display = 'none';
}
trigger.addEventListener('click', () => {
panel.classList.contains('show') ? closePopover() : openPopover();
});
document.addEventListener('click', (event) => {
if (!wrapper.contains(event.target)) closePopover();
});
// Close button inside the panel
panel.querySelector('.ro-popover-close')?.addEventListener('click', closePopover);
ClassRequiredDescription
.ro-popover-toggleYesTrigger. Icon weight increases when the adjacent panel has .show.
.ro-popoverYesPopover panel. Toggle .show + set display: block to open. Sizes: .ro-size-md / .ro-size-lg.
.ro-popover-headerNoHeader row.
.ro-popover-bodyNoMain content (scrollable).
.ro-popover-footerNoFooter actions.
.ro-popover-closeNoClose control — see Close Button.
.ro-no-titleNoTitleless layout; positions close button absolutely.
VariableSet onDescription
--is-popover-shown.ro-popover0 (closed) or 1 (open). Set automatically when .show is present.
--ro-popover-width.ro-popoverPanel width. md → 300px, lg → 500px via size classes.

Changelog

Recent updates in @ringover/styles. See the full package changelog .

@ringover/styles@3.13.0
  • Resynchronized popover with styles molecule.