Skip to main content

Visual Discovery Custom Styling

You can inject custom CSS into the Visual Discovery widget by adding a <style> tag with a specific ID to your page. The widget runs inside a Shadow DOM, so regular page styles don't affect it — this is the supported way to customize its appearance.

How It Works

Place a <style> tag with the ID fs-visual-discovery-custom-styles anywhere on your page. The Visual Discovery init script will automatically clone it into the widget's Shadow DOM at initialization time.

<style id="fs-visual-discovery-custom-styles">
/* Your custom CSS here */
</style>
info

The style tag is cloned into both the widget Shadow DOM and the portal Shadow DOM (used for modals), so your styles apply everywhere in the widget.

Example: Customize Product Card

<style id="fs-visual-discovery-custom-styles">
/* Change product title font size */
.product-title {
font-size: 14px;
}

/* Adjust gallery image aspect ratio */
.gallery-item-card img {
object-fit: contain;
}

/* Custom button styling */
.upload-button {
background-color: #000;
border-radius: 8px;
}
</style>

Out-of-Stock Color Swatches

When a color variant is sold out and still shown on a product card, the widget marks the swatch so you can restyle it:

What we renderWhereUse it?
fs-swatch-out-of-stock classon the swatch element, alongside color-swatchYes — this is the supported hook
<span class="ban">inside the swatchOur default marker: a faint grey ban icon (#ccc, 60% opacity)
(out of stock)in the swatch's aria-labelScreen-reader text, not a visible tooltip
<style id="fs-visual-discovery-custom-styles">
/* Replace the default ban icon with a diagonal strike-through */
.color-swatch.fs-swatch-out-of-stock .ban {
display: none;
}

.color-swatch.fs-swatch-out-of-stock {
opacity: 0.5;
}

.color-swatch.fs-swatch-out-of-stock::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(to bottom right,
transparent calc(50% - 1px), #6e6e6e 50%, transparent calc(50% + 1px));
}
</style>

Sold-out swatches are never selectable in Visual Discovery — clicks and hovers are ignored, and there is no setting to change that.

Two swatch types carry no class, so they need different selectors:

  • Image swatches — target .image-swatch[data-disabled="true"] or .image-swatch .ban
  • Alternative-color swatches (color options linking out to a separate product, with no variant data attached) — marked only if you opt in with mark_oos_alt_swatches: true; otherwise a sold-out alternative color renders identically to an available one
Recoloring the ban icon needs !important

The icon's color is set as an inline fill on the SVG, so .ban svg { fill: red } loses to it — use fill: red !important, or hide the icon as the example above does.

Avoid data-disabled on color swatches

It renders on every color swatch — reading "false" on in-stock ones — and reflects whether the swatch is clickable rather than whether it is sold out. Style on .fs-swatch-out-of-stock. On image swatches it is the only hook available, and there it is reliable.

The variant has to reach the storefront first

No marker can appear if the sold-out variant was already removed server-side. Check all of these before writing CSS:

  • Merchandising → Display Merchandising → Hide Out of Stock Variants — when on, sold-out variants are stripped from the response entirely
  • Out-of-stock product visibility set to Hide — excludes unsellable variants from the index
  • Variant-level out-of-stock filtering, when variant-level attributes are enabled
  • hide_oos_swatches: true in your own options

Important Notes

  • The <style> tag must have the exact ID fs-visual-discovery-custom-styles
  • Only one <style id="fs-visual-discovery-custom-styles"> element is allowed per page — multiple elements with the same ID will cause unpredictable behavior; only the first will be applied
  • The tag must be present on the page before the Visual Discovery widget initializes
  • Styles are cloned once at initialization — dynamic changes after init won't be reflected
  • Use your browser's DevTools to inspect the Shadow DOM and find the correct class names to target
  • To disable Shadow DOM entirely (for debugging), set window.__fast_options = { disable_vd_shadow_root: true } before the widget loads