Popovers
Which Smootify parts can open in a popover, how to build one with two attributes, and the rules for option pickers in a popover.
A popover is a panel that opens above the page, such as a menu, a list of choices or a drawer. The browser opens and closes it: Escape and a click outside close it, and it moves the focus for keyboard and screen reader users. Every panel Smootify opens or closes can be a popover, from the mini cart to the option pickers, the filters and the cookie banner.
Note
Popovers work in Safari 17, Chrome 114, Firefox 125 and later.
Build a popover
A popover is two attributes, and Smootify works the same with every popover you write:
- The panel is an element with the attribute
popover="auto"and anid, such assize-list. - The trigger is a
<button popovertarget="size-list">, with theidof the panel. - Inside a form, such as the add-to-cart form, also give the trigger
type="button". Without it, the trigger submits the form. - To close the panel from inside, add a button with the same
popovertargetandpopovertargetaction="hide". Escape and a click outside also close it.
How it looks.
- The browser shows the panel above everything, in the middle of the window. Place it with your own styles, such as a fixed position on the right for a drawer.
- Smootify takes the browser’s padding and border off every popover, and the class of your panel sets its own. There is no backdrop: the page behind stays as it is. For a backdrop, such as behind a drawer, set the CSS variable
--smootify-backdrop-coloron the panel’s class, for examplergba(0, 0, 0, 0.5). See CSS. - A panel that is a popover only on small screens, such as filters in a column on desktop and in a drawer on mobile: on the panel’s class, set
--smootify-closed-display: flexat the desktop breakpoint, withposition: static,inset: auto,margin: 0and the column’s width, since the browser places every popover fixed in the middle. Set--smootify-closed-display: noneat tablet, so it is a drawer again. - The page under a drawer. A popover that covers the page, such as a cart drawer or a full-screen menu, takes the attribute
data-overflow-body: the page stops scrolling while it is open, and its scrollbar keeps its space so nothing jumps. A popover anchored to its trigger, such as a small menu under a button, leaves it out. It works on a<dialog>too. - To animate a popover, use CSS:
@starting-styleandtransition-behavior: allow-discreteon the panel, as in Write components. The transition plays whoever opens or closes the popover: your trigger, Smootify (the cart after an add to cart, the market suggestion), Escape or a click outside. Smootify adds no animation of its own.
Which parts can use a popover
Each of these parts can open in a popover:
Mini cart
smootify-cart- The mini cart. Build the cart
Option pickers
variant-swatches- The value buttons. Closes after a pick. Product page
variant-popover- The values of an option. Product page
Add-ons and product options
addon-popover- The variants of an add-on. Product add-ons
configurator-popover- A configurator option. Product configurator
dynamic-property(Dropdown type)- The choices. Dynamic properties
Search results
smootify-search- The results. Opens as the visitor types. Predictive search
Pickup locations
store-availability- The other locations, loaded when it opens. Pickup
Back in stock alert
klaviyo-back-in-stock- The alert form. Back in stock
Banners
smootify-consent- The cookie banner. Cookie consent
- The market suggestion
- The popover itself, opened by Smootify a few seconds after the page loads. Market suggestion
On a collection page, auto-close-details="true" on smootify-search-discovery closes every popover inside it each time the results change, such as a filters panel. That includes a popover inside a product card.
Pickers in a popover
These rules apply to variant-popover, addon-popover, filter-popover, sort-popover, configurator-popover, country-switcher, location-switcher and the Dropdown type of dynamic-property:
The trigger goes inside the element
Its text shows the current choice, so it changes when the visitor picks. A fixed label, such as Size, goes outside it.
The first link or button is the template
Smootify copies it for every value and removes the links or buttons next to it. A button with popovertarget does not count.
A pick closes the popover
So do Escape and a click outside. A close button inside needs popovertarget and popovertargetaction=, or it becomes the template.
The attributes are the ones of the *-dropdown version of each picker, such as data-option on variant-popover.
<div>Size</div>
<variant-popover data-option="1">
<button type="button" popovertarget="size-list"><span>M</span></button>
<div id="size-list" popover="auto">
<a href="#"><span option="title">Value</span></a>
</div>
</variant-popover>Here the panel has the id size-list. The label “Size” sits outside the trigger, because the trigger’s text becomes the chosen value.
Popovers in repeated blocks
A popover can sit inside a block Smootify repeats, such as an address, an order or a product card. Each copy gets its own id, and its trigger follows, so each trigger opens its own panel. Design the popover once. On product cards that Astro renders on the server, give each card’s popover its own id and point the trigger’s popovertarget at it: Smootify never reuses an id the page already has.
In a mini cart, a popover anywhere inside smootify-cart makes Smootify open the whole cart as a popover, so keep popovers out of the lines.
Before you publish
Check these first
- The trigger adds to cart or submits the form. It is inside a form without
type="button". - A close button became a value, or disappeared. It is the first button in the popover, so it became the template. Close with a button that has
popovertargetandpopovertargetaction="hide", or leave it to Escape and the click outside. - The label on the trigger is replaced. The trigger’s first text shows the choice. Put a fixed label outside the trigger, or after the text of the choice.
- The choice never shows on the trigger. The trigger is outside the picker element.
- The picker disappears. It has no popover, or the popover has no link or button inside.
- The trigger does nothing. Its
popovertargetis not the exactidof the panel. - The panel opens in the middle of the window. It has no position of its own: place it with your styles.
- The panel never shows on desktop. A closed popover is hidden: set
--smootify-closed-displayon its class at that breakpoint. - Every card opens the same panel. The cards are rendered on the server with one
idfor all their popovers. Give each card’s popover its ownid.