Styling & Customization
Customize the appearance of Zest consent UI
Theming
Zest supports three theme modes:
window.ZestConfig = {
theme: 'auto' // 'light', 'dark', or 'auto'
};
| Theme | Behavior |
|---|---|
light |
Always use light theme |
dark |
Always use dark theme |
auto |
Follow system preference (prefers-color-scheme) |
Accent Color
Customize the primary button color:
window.ZestConfig = {
accentColor: '#0071e3' // Any valid CSS color
};
The accent color is used for:
- “Accept All” button background
- Toggle switches when enabled
- Focus rings and highlights
Validated since v2.0.0. The value is passed through a strict color validator that accepts hex (
#0071e3), named colors (rebeccapurple), and thergb(),rgba(),hsl(), andhsla()functions. Anything else falls back silently to the default.
Banner Position
Control where the banner appears:
window.ZestConfig = {
position: 'bottom-right'
};
| Position | Description |
|---|---|
bottom |
Centered at bottom of page |
bottom-left |
Floating card at bottom-left corner |
bottom-right |
Floating card at bottom-right corner |
top |
Centered at top of page |
top-left |
Floating card at top-left corner (v2.6.0+) |
top-right |
Floating card at top-right corner (v2.6.0+) |
center |
Dead-center of the viewport, fades in with a subtle scale (v2.6.0+) |
Button Style & Layout
Control how the action buttons look and are arranged:
window.ZestConfig = {
buttonStyle: 'fill', // 'fill' (solid) or 'outline' (accent-bordered)
buttonLayout: 'row' // 'row', 'split', or 'split-modern'
};
| Layout | Description |
|---|---|
row |
All buttons in a single row (default) |
split |
Settings/Save on the left, Accept + Reject grouped on the right (v2.6.0+) |
split-modern |
Same as split, but Settings/Save is the primary button and Accept/Reject are secondary (v2.6.0+) |
The split-modern layout draws attention to the preferences action — useful when you want visitors to engage with the settings modal rather than blindly accepting.
Backdrop Blur
Blur the page content behind the modal and hard wall overlay:
window.ZestConfig = {
backdropBlur: 8 // blur radius in pixels, 0 disables
};
The blur applies to both the settings modal overlay and the hard consent wall. Off by default because backdrop-filter can be expensive on low-end devices.
Hard Consent Wall
Block all page interaction until the visitor decides:
window.ZestConfig = {
hardWall: true
};
A full-viewport overlay renders behind the banner, preventing clicks or interaction with the page until the visitor accepts or rejects. The banner becomes aria-modal when the wall is active. Useful for compliance-sensitive sites that need provable awareness — 100% decision visibility.
Hidden Categories
Remove unused consent categories from the settings modal:
window.ZestConfig = {
categories: {
analytics: { hidden: true },
marketing: { hidden: true }
}
};
Hidden categories are forced to false (rejected) — a visitor can never accept a toggle they cannot see. Essential cannot be hidden. Also accepted via data-hide-categories="analytics,marketing".
This solves a real transparency problem: showing empty toggles for categories a site doesn’t use implies data processing that isn’t happening. A site with only embedded YouTube (marketing) and cookieless analytics doesn’t need to show Functional or Analytics toggles.
CSS Custom Properties
Zest uses CSS custom properties that you can override. Since Zest uses Shadow DOM, you need to use the customStyles configuration option:
window.ZestConfig = {
customStyles: `
:host {
--zest-accent: #ff6b35;
--zest-bg: #1a1a2e;
--zest-bg-secondary: #16213e;
--zest-text: #edf2f7;
--zest-text-secondary: #a0aec0;
--zest-border: #2d3748;
--zest-radius: 16px;
--zest-radius-sm: 8px;
}
`
};
Available CSS Variables
| Variable | Default (Light) | Description |
|---|---|---|
--zest-accent |
#0071e3 |
Primary accent color |
--zest-accent-text |
auto | Text color on primary buttons. Uses CSS contrast-color() (Baseline April 2026) with a JS WCAG luminance fallback for older browsers. Light accent colors get dark text automatically (v2.6.0+) |
--zest-overlay |
rgba(0, 0, 0, 0.5) |
Background color of the modal overlay and hard consent wall. One variable, same color everywhere (v2.6.0+) |
--zest-bg |
#ffffff |
Background color |
--zest-bg-secondary |
#f3f4f6 |
Secondary background |
--zest-text |
#1f2937 |
Primary text color |
--zest-text-secondary |
#6b7280 |
Secondary text color |
--zest-border |
#e5e7eb |
Border color |
--zest-radius |
12px |
Large border radius |
--zest-radius-sm |
8px |
Small border radius |
Custom CSS
Inject custom CSS into the Shadow DOM.
Sanitized since v2.0.0.
customStylesis hard-capped at 20 KB, and the following are stripped before injection:@import,@charset,expression(),-moz-binding, and externalurl()values. Selectors targeting the accept/reject buttons (e.g..zest-btn--primary { opacity: 0 }) are also removed to prevent clickjacking via invisible-button attacks. Theme variables and ordinary layout styles are unaffected.
window.ZestConfig = {
customStyles: `
/* Custom banner styles */
.zest-banner {
max-width: 500px;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
}
/* Custom button styles */
.zest-btn--primary {
border-radius: 9999px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
/* Custom modal styles */
.zest-modal {
max-width: 600px;
}
/* Custom widget styles */
.zest-widget {
bottom: 24px;
right: 24px;
}
`
};
CSS Class Reference
Banner:
.zest-banner- Main banner container.zest-banner--bottom/.zest-banner--top/.zest-banner--centeretc. - Position variants.zest-banner-wall- Hard wall overlay (v2.6.0+).zest-banner__title- Banner title.zest-banner__description- Banner description.zest-banner__buttons- Button container.zest-banner__buttons--split- Split layout container (v2.6.0+).zest-banner__buttons-group- Grouped buttons in split layout (v2.6.0+)
Buttons:
.zest-btn- Base button class.zest-btn--primary- Primary action button (Accept All).zest-btn--secondary- Secondary action button (outlined, used in split-modern) (v2.6.0+).zest-btn--ghost- Tertiary button (Settings/Save)
Modal:
.zest-modal-overlay- Background overlay.zest-modal- Modal container.zest-modal__header- Modal header.zest-modal__body- Modal body.zest-modal__footer- Modal footer.zest-modal__footer--split- Split layout footer (v2.6.0+).zest-modal__buttons-group- Grouped buttons in split layout (v2.6.0+)
Categories:
.zest-category- Category item.zest-category__header- Category header.zest-category__label- Category title.zest-category__description- Category description.zest-toggle- Toggle switch
Widget:
.zest-widget- Floating widget button
Custom Labels
Customize all UI text:
window.ZestConfig = {
labels: {
banner: {
title: 'We value your privacy',
description: 'We use cookies to enhance your browsing experience and analyze our traffic.',
acceptAll: 'Accept',
rejectAll: 'Decline',
settings: 'Preferences'
},
modal: {
title: 'Cookie Preferences',
description: 'Manage your cookie preferences below.',
save: 'Save',
acceptAll: 'Accept All',
rejectAll: 'Reject All'
},
widget: {
label: 'Cookies'
},
categories: {
essential: {
title: 'Essential',
description: 'Required for the website to function properly.'
},
functional: {
title: 'Functional',
description: 'Remember your preferences and settings.'
},
analytics: {
title: 'Analytics',
description: 'Help us understand how visitors use our site.'
},
marketing: {
title: 'Marketing',
description: 'Used to deliver relevant advertisements.'
}
}
}
};
Examples
Minimal Dark Theme
window.ZestConfig = {
theme: 'dark',
position: 'bottom-right',
accentColor: '#10b981',
customStyles: `
.zest-banner {
border: 1px solid var(--zest-border);
}
.zest-btn {
font-size: 14px;
}
`
};
Corporate Style
window.ZestConfig = {
theme: 'light',
position: 'bottom',
accentColor: '#1e40af',
customStyles: `
:host {
--zest-radius: 4px;
--zest-radius-sm: 2px;
}
.zest-banner {
border-top: 3px solid var(--zest-accent);
}
.zest-btn {
font-family: 'Inter', sans-serif;
text-transform: uppercase;
font-size: 12px;
letter-spacing: 0.1em;
}
`
};
Playful Style
window.ZestConfig = {
theme: 'auto',
position: 'bottom-left',
accentColor: '#f97316',
customStyles: `
:host {
--zest-radius: 24px;
--zest-radius-sm: 12px;
}
.zest-banner {
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
}
.zest-btn--primary {
border-radius: 9999px;
padding: 12px 24px;
}
`
};
Hiding the Widget
Disable the floating widget:
window.ZestConfig = {
showWidget: false
};
You can still provide a way for users to change preferences:
<button onclick="Zest.showSettings()">Cookie Settings</button>