Developers
Start building
Themes/Chrome stable classes

Chrome stable classes

The class hooks the platform guarantees on brand, cart, user menu, promo, chat, locale banner and card chrome, and how a theme overrides them from its own CSS.

On this page

The platform supplies default parts for the brand, cart, user menu, promo bar, chat, locale banner and product cards. Themes render them through the SDK or through the platform blocks in their header and footer. Restyle these parts through the stable classes below. The classes exist only on the platform's parts, not on markup a theme or merchant writes.

Each class is a bare kebab-case token on the element's className. It carries no styling of its own and is part of the theme contract: the platform may change the Tailwind utilities around it, never the token.

The override pattern

Write the rules in your theme's src/styles/theme.css, unlayered, with :where():

src/styles/theme.css
:where(.header-brand) {
  letter-spacing: 0.08em;
}

:where(.cart-count) {
  background: var(--color-surface);
  border-color: var(--color-line);
}

Two things make this work:

  • Unlayered CSS beats Tailwind. The platform's utilities live in @layer utilities. An unlayered rule wins against every layered one regardless of specificity, so you need neither !important nor a more specific selector.
  • :where() keeps specificity at 0. Your rule stays the easiest thing in the cascade to override, so a later rule of your own, or a state class on the same element, still wins. Source order becomes the override mechanism.

header-brand sits on the link drawn by Brand and Logo from @poltura/theme-sdk/chrome and by the logo block. Those also render in most theme footers, so a bare .header-brand rule reaches the footer logo too. Scope footer-only rules through your own footer class.

The classes

ClassSurfaceNotes
header-brandbrandthe brand link: Brand, Logo and the logo block
header-brand-markbrandsquare initial badge drawn when the store has no logo
header-brand-labelbrandthe store name drawn when the store has no logo
cart-buttoncartCartButton trigger <button> (also carries data-cart='header')
cart-countcartitem count badge
cart-button-labelcartthe trigger's text label
cart-panelcartdesktop popover and mobile sheet content
cart-panel-titlecartpanel heading
user-menu-triggeruser menuUserMenu (and the account block) trigger <button>
user-menu-contentuser menudropdown content root
user-menu-labeluser menuevery label in the menu
promo-barpromo barPromoBar strip root
promo-bar-innerpromo barcentred container
promo-bar-linkpromo barthe announcement link
inbox-rootchat widgetfixed-position wrapper (data-poltura-inbox)
inbox-launcherchat widgetlauncher button
inbox-panelchat widgetdialog root
inbox-panel__headerchat widgettitle and close row
inbox-messageschat widgetscroll region (role="log")
inbox-message-rowchat widgetwrapper for author, bubble and metadata; --system for system text
inbox-messagechat widgetactual bubble only; plus --customer, --staff, --ai
inbox-composerchat widgettext field, attach and send
inbox-statuschat widgetoffline / reconnecting line
inbox-offlinechat widgetoffline capture form
locale-bannerlocale bannerLocaleBanner suggestion dialog root
locale-banner-innerlocale bannerpadded body
locale-banner-switchlocale bannerprimary "switch language" button
locale-banner-staylocale bannersecondary "stay" button
product-card-bodyproduct cardProductCard content column
product-card-titleproduct cardproduct title
product-card-priceproduct cardprice block
featured-view-all-mobileproduct railthe "view all" link under a ProductRail on small screens
theme-section-bandbuilt-in sectionsa full-bleed band section root
theme-section-centeredbuilt-in sectionsa centred content column inside a section

The full list of chat widget classes is on Chat widget chrome.

Header states

The header is a section group (layout/header.json), so its pieces are elements that carry the merchant's own style settings rather than class hooks. Its scroll state is exposed as attributes for CSS:

AttributeOnMeaning
data-theme-chrome='header'the pinned header boxthe promo bar and header together
data-header-behaviorthe pinned header boxstatic, sticky or reveal
data-header-overlaythe pinned header boxthe header lies over the first section on this page
data-header-scrolledthe pinned header boxthe page has scrolled past the header
data-header-hiddenthe pinned header boxa revealing header is hidden while the shopper scrolls down
data-header-shrink, -shrunkthe pinned header boxthe header shrinks once scrolled, and has shrunk
data-header-sectionthe header section rootthe header bar
data-header-mobile-fromthe header section rootmobile, tablet or desktop: where the drawer takes over
:where([data-theme-chrome='header'][data-header-scrolled]) [data-header-section] {
  box-shadow: 0 1px 0 var(--border);
}

useHeaderVisibility() from @poltura/theme-sdk/chrome reads the same scrolled and hidden states in code.

Floating elements

Anything a theme pins to the bottom of the viewport (a sticky buy bar, a floating button, its own banner) adds three offsets to its bottom, each 0px when unset:

VariableSet while
--banner-bottom-offseta bottom banner bar is showing (its height)
--preview-bar-offsetthe private-preview bar is showing (its height)
--poltura-editor-inset-bottomthe page is on the Customizer canvas and the Customizer covers its bottom (on phones)
:where(.my-sticky-buy) {
  position: fixed;
  bottom: calc(
    var(--banner-bottom-offset, 0px) + var(--preview-bar-offset, 0px) +
      var(--poltura-editor-inset-bottom, 0px)
  );
}

The platform's chat launcher, back-to-top button, banners and cookie bar already do this. --poltura-editor-inset-bottom exists only inside the Customizer, so the live storefront is unchanged. Without it, an element pinned to the bottom sits under the Customizer's tab bar or settings sheet on a phone.

What is not hooked

The header's menu, search and language blocks, MainNav, MobileNav, MegaMenu, MobileMenu, HeaderSearch and LocaleSwitcher carry no class hooks. Style them through the element's style settings, the className and classes props the SDK parts take (see the chrome, navigation and search references), the header attributes above, or their containers.

Next

Last updated