logo

Configurator Styling

Customize the OV25 configurator UI with Shadow DOM, CSS variables, data attributes, and class names.

This document explains how to customize the OV25 configurator UI: Shadow DOM and why styles must pass through inject, display modes, global CSS variables, data attributes, class names, and the ov: Tailwind prefix.


1. Overview: Shadow DOM and Why Inject Is Needed

Many configurator components render inside Shadow DOM. Shadow roots do not inherit styles from the host document, so custom styles must be passed via branding.cssString in the inject config. Without this, your CSS will not reach the configurator UI.

Components by Shadow DOM Usage

ComponentShadow DOM?Notes
Gallery, Price, NameNoRender in document; inherit document styles
Variants, Swatches, Configure button, CarouselYesUse Shadow DOM; require branding.cssString

Source: src/utils/inject.tsxshouldCreateShadowDOM returns false only for gallery, price, name.

Global Shadow Containers

Created by inject, each receives [sharedStylesheet, cssVariablesStylesheet(cssString)]:

  • ov25-mobile-drawer-container
  • ov25-configurator-view-controls-container
  • ov25-popover-portal-container
  • ov25-toaster-container
  • ov25-swatchbook-portal-container

2. Passing Custom Styles

Use branding.cssString in your inject config:

branding: {
  cssString: `
    .ov25-variant-control { background-color: red; }
    #ov25-variants-header { background: #1a1a1a !important; }
  `,
},

How branding.cssString Is Applied

  • Shadow DOM: createCSSVariablesStylesheet(cssString) is appended to each shadow root's adoptedStyleSheets.
  • Document: setupCSSVariables(cssString) adds the same stylesheet to document.adoptedStyleSheets for light-DOM components (gallery, price, name).

Reference: dev/react-test/tests/single-custom-css.jsx.


3. Display Modes and Their Styling Hooks

Variant Display Modes

ModeData AttributeCSS Variables
Wizarddata-ov25-wizard-variants-mode="inline" | "drawer"--ov25-wizard-variants-content-height, --ov25-wizard-variants-filter-height
Listdata-ov25-list-variants-mode="inline"Uses --ov25-wizard-variants-content-height
Tabsdata-ov25-tabs, data-ov25-tab, data-ov25-tab-id, data-ov25-tab-active
Treedata-ov25-tree-variants-mode={mode}
Accordiondata-ov25-accordion-variants-mode={mode}

Inline vs Sheet/Drawer

  • data-ov25-inline-list on #ov25-aside-menu when variants are inline.
  • Variables: --ov25-inline-list-aside-min-height, --ov25-inline-list-aside-max-height-mobile.

Snap2 Variants Panel

  • data-ov25-variants-panel, data-open="true" for the slide panel.
  • Styled in globals.css.

4. Global CSS Variables Reference

Override these in :root or via branding.cssString to theme the configurator.

Color Variables

VariableDefaultPurpose
--ov25-background-color#ffffffMain background
--ov25-secondary-background-color#f6f6f6Secondary background
--ov25-text-colorblackPrimary text
--ov25-secondary-text-color#000000Secondary text
--ov25-primary-colorrgb(65, 65, 65)Buttons, accents
--ov25-border-color#E5E5E5Borders
--ov25-border-color-secondary#282828Dark borders
--ov25-hover-coloroklch(...)Hover states
--ov25-color-handle#000000Drawer handle
--ov25-cta-color#22c55eCTA buttons
--ov25-cta-color-hover#16a34aCTA hover
--ov25-cta-color-light#4ade80CTA light
--ov25-destructive#ef4444Destructive actions
--ov25-highlight-color#00fbffHighlights

Layout and Sizing

VariablePurpose
--ov25-rounded, --ov25-rounded-xs--ov25-rounded-fullBorder radius scale
--ov25-button-border-radius, --ov25-button-border-widthButton styling
--ov25-gallery-gapGap between gallery and carousel
--ov25-configurator-iframe-background-color, --ov25-configurator-iframe-border-radiusIframe styling
--ov25-variant-thumb-border-radiusVariant thumbnails

Typography

VariablePurpose
--ov25-text-xs-size--ov25-text-xl-sizeFont sizes
--ov25-text-xs-line-height--ov25-text-xl-line-heightLine heights
--ov25-360-font-family360° label font

Display-Mode-Specific

VariableUsed By
--ov25-wizard-variants-content-heightWizard/list inline
--ov25-wizard-variants-filter-heightWizard filter bar
--ov25-inline-list-aside-min-heightInline list aside
--ov25-inline-list-aside-min-height-mobile, --ov25-inline-list-aside-max-height-mobileMobile inline list

View Controls and Overlays

VariablePurpose
--ov25-configurator-view-controls-text-colorOverlay controls text
--ov25-overlay-button-colorOverlay button background
--ov25-configurator-variant-drawer-handle-colorDrawer handle

Swatch Flash Animations

VariableDefaultPurpose
--ov25-swatch-flash-duration0.5sDuration for swatch icon and count flash animations

Note: --ov25-text-md-size is referenced in #ov25-mobile-savings-amount but not defined in :root; use an existing variable or add it.


5. Class Names and Data Attributes for Targeting

Use these selectors in branding.cssString to target specific UI elements.

Stable Class Names

ClassComponentPurpose
.ov25-variant-controlProductOptionsOption wrapper
.ov25-variant-nameDefaultVariantCardVariant name
.ov25-variant-thumb-wrapperVariantThumbThumbnail wrapper
.ov25-variant-thumb-overlayVariantThumbOverlay
.ov25-variant-card-gradientVariantThumbVariant card overlay gradient
.ov25-variant-image-containerVariantThumbImage container
.ov25-selection-thumbnailSelection thumbnailsFabric icons, etc.
.ov25-carousel-tabTabsTab styling
.ov25-group-nameGroup labelsGroup name
.ov25-swatch-iconSwatch iconsSVG styling
.ov25-gradientTabs, VariantThumb, OVOrBrandLogoGradient; hardcoded, no variable
.radial_gradientVariantThumbRadial gradient overlay on variant cards
.shadow-inner-intenseVariantThumbInner shadow on variant cards
.ov25-dimensions-width, .ov25-dimensions-height, .ov25-dimensions-depth, .ov25-dimensions-miniIframe dimensions3D viewer dimensions (styled via cssString sent to iframe)
.ov25-thumbnail-scrollCarouselHides scrollbar
.ov25-controls-textHidden by default
.ov25-swatch-flash-destructive, .ov25-swatch-flash-ctaFilterControlsSwatch icon flash animations
.ov25-swatch-count-flash-destructive, .ov25-swatch-count-flash-ctaFilterControlsSwatch count text flash animations

6. SwatchBook

SwatchBook has its own set of IDs and classes for customization.

ID / ClassPurpose
#ov25-selected-swatches-containerSwatches summary trigger (click opens SwatchBook)
#ov25-swatchbookSwatch book dialog
#ov25-swatchbook-titleDialog title
#ov25-swatchbook-featuredFeatured/zoomed swatch area
#ov25-swatchbook-contentMain content area
#ov25-swatchbook-emptyEmpty state container
#ov25-swatchbook-swatches-listSwatch grid
#ov25-swatchbook-controlsFooter controls
#ov25-swatchbook-add-to-cart-buttonAdd-to-cart button wrapper
#ov25-swatchbook-add-buttonAdd button
.ov25-selected-swatch-image-containerFeatured swatch image wrapper
.ov25-selected-swatch-name, .ov25-selected-swatch-option, .ov25-selected-swatch-sku, .ov25-selected-swatch-descriptionFeatured swatch text
.ov25-swatch-itemSingle swatch card
.ov25-swatch-image-containerSwatch image wrapper
.ov25-swatch-imageSwatch image
.ov25-swatch-zoom-buttonZoom overlay on swatch
.ov25-swatch-zoom-in-icon, .ov25-swatch-zoom-out-iconZoom icons (.group:hover increases opacity)
.ov25-empty-swatch-squareEmpty slot placeholder
.ov25-swatchbook-empty-title, .ov25-swatchbook-empty-descriptionEmpty state text

7. Data Attributes

AttributeValuesPurpose
data-ov25-wizard-variants-modeinline, drawerWizard layout
data-ov25-list-variants-modeinlineList layout
data-ov25-tree-variants-modeTree layout
data-ov25-accordion-variants-modeAccordion layout
data-ov25-inline-list(present)Inline list on aside
data-ov25-variants-panelSnap2 variants panel
data-ov25-option-idoption IDOption container
data-ov25-variant-optionoption IDVariant option
data-ov25-tabs, data-ov25-tab, data-ov25-tab-id, data-ov25-tab-activeTabs
data-ov25-tabs-containerTabs wrapper
data-ov25-tabs-dropdownDropdown tab mode
data-ov25-tab-selectTab select element
data-ov25-swatch-book-button, data-ov25-swatch-book-countSwatch book
data-ov25-configure-buttonConfigure button
data-open"true"Snap2 variants panel open state
data-stacked"true"Iframe container stacked carousel layout

8. IDs

IDPurpose
#ov25-aside-menuAside container
#ov25-controlsVariants container
#ov25-configurator-variant-menu-containerVariant menu
#ov25-variants-headerVariants header (hardcoded background: #0c5358)
#ov25-variants-header-mobileMobile variants header
#ov25-variant-group-contentVariant group content
#ov25-option-selector-tabsTabs container
#ov25-price-containerPrice container
#ov25-product-carouselCarousel
#ov25-drawer-toggle-buttonMobile drawer toggle
#ov25-drawer-contentDrawer content
#ov25-provider-rootReact root
#ov25-configurator-iframe-containerIframe container
#ov25-mobile-price-containerMobile price wrapper
#ov25-mobile-savings-amountMobile savings text
#ov25-mobile-subtotalMobile subtotal
#ov25-mobile-priceMobile price
#true-ov25-configurator-iframe-containerReplaced gallery container (carousel sibling)
#true-carouselCarousel wrapper when stacked

9. Tailwind Prefix (ov:)

All Tailwind utilities use the ov: prefix (e.g. ov:flex, ov:p-2). This avoids clashes with host page Tailwind. Custom styles should not rely on unprefixed Tailwind classes from the configurator.


10. Iframe Dimensions Styling

The dimensions overlay (width, height, depth) is rendered inside the 3D iframe. cssString is sent via VIEW_DIMENSIONS and VIEW_MINI_DIMENSIONS messages. Target these classes in your branding.cssString:

  • .ov25-dimensions-width
  • .ov25-dimensions-height
  • .ov25-dimensions-depth
  • .ov25-dimensions-mini

Example: dev/react-test/tests/single-custom-css.jsx.


11. Replaced Elements

When replace: true on a selector, the host element gets ov25-configurator-{componentName} (e.g. ov25-configurator-gallery, ov25-configurator-variants). Use these to target replaced containers from outside Shadow DOM.


12. Hardcoded Values

These are not driven by CSS variables; override with !important or higher specificity if needed:

  • #ov25-variants-header: background: #0c5358
  • .ov25-gradient: linear-gradient(90deg, #26E8FE 0%, #808AFF 50%, #A41EFE 100%)

13. Examples

Override CSS variables

branding: {
  cssString: `
    :root {
      --ov25-primary-color: #1a1a1a;
      --ov25-cta-color: #2563eb;
    }
  `,
},

Target variant controls

branding: {
  cssString: `
    .ov25-variant-control {
      background-color: #f5f5f5;
      border-radius: 8px;
    }
  `,
},

Style dimensions overlay (inside iframe)

branding: {
  cssString: `
    .ov25-dimensions-width, .ov25-dimensions-height, .ov25-dimensions-depth, .ov25-dimensions-mini {
      border: 2px dashed green;
      scale: 1.2;
    }
  `,
},

Customize SwatchBook

branding: {
  cssString: `
    #ov25-swatchbook { border-radius: 16px; }
    .ov25-swatch-item { border: 1px solid #e5e5e5; }
    .ov25-swatchbook-empty-title { font-size: 1.25rem; }
  `,
},

Override variants header

branding: {
  cssString: `
    #ov25-variants-header {
      background: #1a1a1a !important;
    }
  `,
},