Skip to content
vviinn DocsDocs Beta

Styling Specific Elements

Need to style just the upload button? Or change how a title looks? CSS Parts give you precise control over individual widget elements.

Use the ::part() selector to target specific parts that regular CSS can’t reach. Learn more about Shadow Parts.

Each widget exposes specific elements you can style. Find available parts in two ways:

  1. Playground section — View the complete list at the bottom of the Controls tab (right sidebar) in Storybook. For example, check Discovery Slider parts.
  2. Browser DevTools — Inspect the widget element and look for part attributes in the shadow DOM.

Use the tag of the widget you actually embed as the host — e.g. vviinn-vpr-widget or vviinn-vps-widget. Product Card parts are forwarded up to that widget, so the part names stay the same:

/* Single part on the widget you embed */
vviinn-vpr-widget::part(custom-label-0) {
display: block;
}

Part names stay the same whichever widget you embed: a nested component re-exports its own parts (Product Card does this), and rendering directly inside the widget’s shadow tree lets ::part() reach them across that single boundary — you re-export nothing yourself. It only breaks when a part sits more than one shadow boundary away from the tag you select — e.g. a widget rendered inside another widget’s shadow — which is why vviinn-vpr-button forwards its sidebar’s parts explicitly.

Tip: You can combine multiple parts in a selector to target an element that carries both — the same works from any host widget*:

/* Target an element that has both parts */
vviinn-vps-widget::part(custom-label-1 custom-label-image) {
border-radius: 8px;
padding: 4px;
}

* Except vviinn-vpr-button — it only opens a separate vviinn-recommendations-sidebar, so vviinn-vpr-button::part(...) reaches nothing. Target the sidebar: vviinn-recommendations-sidebar::part(title).

Discovery Slider: styling Product Card’s title

Section titled “Discovery Slider: styling Product Card’s title”

Discovery Set: styling widget’s title and discount label

Section titled “Discovery Set: styling widget’s title and discount label”

Product Card: styling custom labels and changing order

Section titled “Product Card: styling custom labels and changing order”

Custom labels are hidden by default, so you need to override the display property to show them. The code example also demonstrates how to change the order of the elements: set an order property for each displayed part of the Product Card.

Custom content placed in a widget’s default slot (e.g. an SVG icon inside vviinn-vps-button or vviinn-vpr-button — same approach for both) can be styled two ways depending on where the stylesheet lives.

Slotted elements live in the light DOM, so plain descendant selectors reach them from any stylesheet on the page. The same selectors work for vviinn-vpr-button.

When the stylesheet is loaded via the widget’s css-url prop, it lives inside the widget’s shadow root. Use ::slotted() to reach the same elements from that scope:

/* loaded via <vviinn-vps-button css-url="..."> */
:host ::slotted(svg) {
width: 32px;
height: 32px;
}

Pick whichever scope matches where your stylesheet is hosted.

Note: Applies only to the default slot (no slot= attribute). Content in named slots (e.g. slot="vviinn-image-upload-icon") is forwarded into nested components — style it via CSS Parts or CSS Variables instead.