Preparing the latest guides, releases, and feature request updates.
Loading guides
Preparing the right Knowledge Base content for this platform.
Custom CSS for the product customizer | Chamevo Support Center
Custom CSS for the product customizer
How to style the Chamevo product customizer using CSS custom properties and the ::part() pseudo-element.
Updated April 29, 20265 min read
Chamevo's product customizer is a Stencil web component (<cv-customizer>) that uses Shadow DOM. Shadow DOM encapsulates component styles, so regular CSS selectors cannot reach inside it. The old fpd- class selectors used in earlier versions no longer work.
There are two supported ways to style the customizer from your theme or stylesheet:
CSS custom properties (--cv-*) β override theme tokens that cascade through the shadow boundary.
::part() pseudo-element β target named shadow DOM parts exposed by the component.
Where to add custom CSS
Option 1: WordPress Customizer
Go to Appearance β Customize β Additional CSS. This stylesheet loads after plugin styles and affects the full page.
Option 2: Child theme stylesheet
Add rules to your child theme's style.css.
Option 3: UI Composer β Custom CSS field
In Chamevo β UI Composer, open a layout and add CSS in the Custom CSS field. This CSS is injected into <head> on pages using that layout, and is the most targeted option when different products need different styles.
All three locations support CSS custom properties and ::part() selectors.
CSS custom properties
CSS custom properties cascade through the shadow DOM boundary. Override them on cv-customizer (or any ancestor element) to change the customizer's colors, spacing, and layout without ::part().
Accent color β buttons, active states, focus rings
--cv-secondary
#8b8d98
Secondary text and icons
--cv-bg
#fcfcfd
Main panel and module background
--cv-bg-secondary
#f8f8f8
List hover states, secondary surfaces
--cv-bg-tertiary
#f0f0f3
Chip backgrounds, tertiary surfaces
--cv-canvas-bg
#ffffff
Canvas area background
--cv-text
#1c2024
Primary text
--cv-text-secondary
#60646c
Labels, placeholders, meta text
--cv-on-primary
#ffffff
Text on primary-colored elements
--cv-border
#d9d9e0
Dividers and non-interactive borders
--cv-border-interactive
#cdced6
Input, button, and card borders
--cv-border-hover
#b9bbc6
Hovered border color
--cv-success
#30a46c
Success indicators
--cv-error
#e5484d
Error indicators
--cv-warning
#ffc53d
Warning indicators
Border radius tokens
Property
Default
Purpose
--cv-radius-sm
0.25rem
Small elements (chips, tags)
--cv-radius
0.375rem
Default radius (inputs, cards)
--cv-radius-lg
0.5rem
Larger elements (panels, dropdowns)
Layout tokens
Property
Default
Purpose
--cv-mainbar-width
70px
Width of the vertical module navigation bar
--cv-sidebar-width
280px
Width of the module content panel (sidebar mode)
--cv-panel-width
260px
Module panel width (dialog/overlay mode)
--cv-toolbar-height
48px
Element editing toolbar height
--cv-actions-bar-height
40px
Actions bar height
Customizer dimensions
These tokens control the overall size of the customizer container. Override them on cv-customizer to make the customizer taller, shorter, or fixed to an exact height.
Property
Default
Purpose
--cv-customizer-height
700px
Target height of the customizer container
--cv-customizer-min-height
500px
Smallest height the customizer can shrink to
--cv-customizer-max-height
70vh
Largest height the customizer can grow to
--cv-customizer-bg
var(--cv-bg-secondary) (#f8f8f8)
Customizer container background (behind the canvas and panels)
The three height tokens work together. The rendered height equals --cv-customizer-height, but it never drops below --cv-customizer-min-height and never exceeds --cv-customizer-max-height. With the defaults, the customizer aims for 700px but caps at 70vh on shorter screens, so it always fits the viewport.
To set a fixed height, match all three tokens:
/* Lock the customizer to exactly 800px tall */
cv-customizer {
--cv-customizer-height: 800px;
--cv-customizer-min-height: 800px;
--cv-customizer-max-height: 800px;
}
On small screens (mobile), the customizer switches to a fluid layout where --cv-customizer-min-height becomes 90vh and --cv-customizer-max-height becomes 100vh. To change the mobile height, override these tokens inside a media query:
/* Make the customizer fill the full screen on mobile */
@media (max-width: 768px) {
cv-customizer {
--cv-customizer-min-height: 100vh;
}
}
Scrollbar tokens
Property
Default
Purpose
--cv-scrollbar-thumb
rgb(0 0 0 / 0.2)
Scrollbar thumb color
--cv-scrollbar-track
transparent
Scrollbar track color
--cv-scrollbar-size
6px
Scrollbar width
Override example
/* Change the accent color and widen the module sidebar */
cv-customizer {
--cv-primary: #e11d48;
--cv-sidebar-width: 320px;
}
Pre-built style classes
Apply these classes to <cv-customizer> or any ancestor to activate built-in style presets.
Class
Effect
cv-dark
Dark color scheme β overrides all surface, text, and border tokens
cv-style-rounded
Larger radii (--cv-radius: 0.75rem) and softer shadows
cv-style-sharp
Zero radii and minimal shadows
To apply a class from PHP (for example, always dark mode):
/* All customizers on the site use the rounded style */
cv-customizer {
--cv-radius: 0.75rem;
--cv-radius-sm: 0.5rem;
--cv-radius-lg: 1rem;
}
::part() selectors
::part() lets you style specific elements inside the shadow DOM from an external stylesheet. All parts below are exposed on cv-customizer β either defined directly or re-exported from child components.
Layout parts
Selector
Target
cv-customizer::part(base)
Root container div
cv-customizer::part(main)
Main layout area (contains nav, canvas, panel)
cv-customizer::part(canvas-area)
Canvas wrapper region
cv-customizer::part(canvas-scroll)
Scrollable canvas container
cv-customizer::part(canvas-sizer)
Canvas sizing div
cv-customizer::part(canvas)
The FabricJS canvas element wrapper
cv-customizer::part(canvas-lock-overlay)
Overlay shown when canvas is locked
Navigation bar (module nav)
Selector
Target
cv-customizer::part(mainbar)
The module navigation bar (vertical or horizontal)
cv-customizer::part(mainbar-item)
Individual module nav button
cv-customizer::part(mainbar-vertical)
Navigation bar when in vertical (side) orientation
cv-customizer::part(mainbar-horizontal)
Navigation bar when in horizontal (bottom) orientation
Module panel
Selector
Target
cv-customizer::part(module-panel)
The module content panel
cv-customizer::part(module-header)
Module panel header bar
cv-customizer::part(module-content)
Module panel scrollable content area
Actions bar
Selector
Target
cv-customizer::part(actions-bar)
Any actions bar instance
cv-customizer::part(actions-bar-top)
Top actions bar
cv-customizer::part(actions-bar-bottom)
Bottom actions bar
Element editing toolbar
The toolbar appears when an element is selected on the canvas. The top-level tools (Edit, Color, Font, Size, Format, Effect, Filters, Transform, Position) are rendered into toolbar-nav. The Color tool reveals a second row of sub-tabs (Fill, Patterns, Stroke, Shadow), each individually targetable. The Color tool's Fill sub-tab also shows an opacity slider, which is exposed as its own part.
Selector
Target
cv-customizer::part(toolbar)
The element editing toolbar
cv-customizer::part(toolbar-nav)
Toolbar navigation tab strip
cv-customizer::part(toolbar-body)
Toolbar content area
cv-customizer::part(toolbar-subtabs)
Color sub-tab strip (Fill / Patterns / Stroke / Shadow)
cv-customizer::part(toolbar-subtab)
Any color sub-tab pill
cv-customizer::part(toolbar-subtab-fill)
Fill sub-tab
cv-customizer::part(toolbar-subtab-patterns)
Patterns sub-tab
cv-customizer::part(toolbar-subtab-stroke)
Stroke sub-tab
cv-customizer::part(toolbar-subtab-shadow)
Shadow sub-tab
cv-customizer::part(opacity)
Opacity slider (shown under the Color tool's Fill sub-tab)
Image module (Upload / Pixabay / AI / QR Code)
The Image module renders a tab strip with up to four tabs depending on configuration: Upload, Pixabay, Text-to-Image (AI), and QR Code. Each tab is exposed as its own part.
Useful when you want elements selectable but not editable on the frontend:
cv-customizer::part(toolbar) {
display: none;
}
Hide a specific module button in the navigation bar
Individual module navigation buttons share the same mainbar-item part, so ::part() alone cannot target one specific module. Use the position-based selector :nth-child() as a CSS fallback:
/* Hide the third module button in the navigation bar */
cv-customizer::part(mainbar-item):nth-child(3) {
display: none;
}
The order matches the mainBarModules array in your Chamevo configuration. Because this is position-based, it breaks if you reorder modules. The reliable way to remove modules is to omit them from mainBarModules in your chamevo_app_options filter:
You cannot select inside a part.::part(mainbar-item) span does not work. You can only style the part element itself.
You cannot target by inner attribute. Individual modules, actions, and tools use data-module, data-action, and data-tool attributes inside the shadow DOM. These are not reachable from external CSS. For per-item targeting, remove the item from configuration instead (e.g. mainBarModules, actions).
You can chain pseudo-classes and the part's own attributes.::part(toolbar-subtab):hover and ::part(toolbar-subtab)[aria-selected="true"] both work.
::part() cannot set custom properties that cascade inside the shadow tree. Set --cv-* on cv-customizer instead.
Apply dark mode to specific pages
/* Only on pages with the class 'my-dark-page' */
.my-dark-page cv-customizer {
--cv-bg: #111113;
--cv-bg-secondary: #18191b;
--cv-bg-tertiary: #212225;
--cv-canvas-bg: #1b1b1f;
--cv-text: #edeef0;
--cv-text-secondary: #b0b4ba;
--cv-border: #363a3f;
--cv-border-interactive: #43484e;
}
Or use the built-in class:
.my-dark-page cv-customizer {
/* Activates the built-in dark preset */
}
/* Apply cv-dark class conditionally */
add_filter('chamevo_app_options', function($options) {
if (/* your condition */) {
$options['customizerClass'] = 'cv-dark';
}
return $options;
});
FAQ
Q: The old .fpd- class selectors stopped working after I updated. Why?
A: Chamevo v2 replaced the legacy fpd-js rendering engine with chamevo-js, which uses Stencil web components and Shadow DOM. Shadow DOM encapsulates styles, so fpd- class selectors no longer reach the customizer's internals. Use --cv-* custom properties or ::part() selectors instead.
Q: Can I override --cv-* properties inside a ::part() rule?
A: No. ::part() rules target elements but cannot set custom properties that cascade into the shadow tree. Set --cv-* on cv-customizer or an ancestor instead.
Q: Do ::part() selectors work in all browsers?
A: Yes. ::part() is supported in all modern browsers (Chrome, Firefox, Safari, Edge). It is not supported in Internet Explorer, which Chamevo does not support.
Q: Can I use JavaScript to add CSS classes to <cv-customizer>?
A: Yes. document.querySelector('cv-customizer').classList.add('cv-dark') works and will apply the corresponding CSS tokens.
Q: How do I hide a specific tab inside the Image module?
A: Each image source has its own ::part(). Hide the QR Code tab with cv-customizer::part(images-tab-qrcode) { display: none; }, the Pixabay tab with images-tab-pixabay, the AI tab with images-tab-text2img, or the upload tab with images-tab-upload.
Q: How do I hide the Shadow tab on the color toolbar?
A: Use cv-customizer::part(toolbar-subtab-shadow) { display: none; }. The same pattern works for toolbar-subtab-fill, toolbar-subtab-patterns, and toolbar-subtab-stroke.
Q: How do I stop customers from changing element opacity?
A: Hide the opacity slider with cv-customizer::part(opacity) { display: none; }. It appears under the Color tool's Fill sub-tab when an element is selected.
Q: Can I hide a single module from the navigation bar with CSS?
A: Only by position with :nth-child() β ::part(mainbar-item) targets every module button uniformly. For a reliable, language-independent way to remove modules, set mainBarModules through the chamevo_app_options filter and omit the modules you do not want.
Q: How do I change the height of the product customizer?
A: Override --cv-customizer-height on cv-customizer. The customizer also respects --cv-customizer-min-height (default 500px) and --cv-customizer-max-height (default 70vh). To set an exact height, match all three tokens to the same value.
Q: The customizer is shorter than the height I set. Why?
A: The height is capped by --cv-customizer-max-height, which defaults to 70vh. On shorter screens this limit wins over --cv-customizer-height. Raise or remove the cap by setting --cv-customizer-max-height to a larger value.