Customizing the Web Messenger with CSS
This guide is the complete reference for styling the web messenger with CSS. It covers CSS variables, class selectors, injection methods, and ready-to-use recipes.
For UI-based customization (colors, avatars, features, privacy settings), see Customizing the Web Messenger.
Injecting Custom CSS
There are four ways to apply custom CSS to the messenger.
1. Custom CSS Field (Dashboard)
The simplest approach. Open the Appearance settings for your bot and paste your CSS into the Custom CSS field. This CSS is injected directly into the widget.

2. Host Page Style Tag
Add a <style> tag with the data-fxo attribute on your host page. The widget automatically extracts this CSS and applies it inside the iframe.
<style data-fxo>
.fxo-header {
background-color: navy;
}
.fxo-launcher {
transform: scale(1.2);
}
</style>
This is useful when you want your CSS bundled with your site rather than managed in the Flow XO dashboard.
3. External Stylesheet
Host your CSS at a URL and load it into the widget. Only https:// URLs are allowed. Pass the URL via customCssUrl using the initialization hook:
<script>
window.onFlowXOInit = function(connectionId) {
return {
config: {
customCssUrl: 'https://example.com/styles/widget.css'
}
};
};
</script>
<script src="https://messenger.flowxo.com/loader.js"
data-connection="YOUR_CONNECTION_TOKEN"
async></script>
This is a good option when multiple bots or pages share the same styles, or when your CSS is generated by a build process.
4. Programmatic CSS (JavaScript API)
You can inject CSS at runtime using FlowXO.setConfig(). This gives you full control — for example, generating styles dynamically based on page context or user preferences.
FlowXO.setConfig({
customCss: `
.fxo-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.fxo-widget {
--fxo-font-family: 'Inter', system-ui, sans-serif;
}
`
});
For more on the JavaScript API, see Going Deeper with the JavaScript API.
CSS Variables
The widget exposes CSS custom properties for controlling colors, typography, dimensions, and more. Override these in your custom CSS.
Brand Colors
:root {
--fxo-primary: #6f5fe8;
--fxo-primary-hover: #5b4dd4;
--fxo-primary-light: #ebe9fc;
--fxo-accent: var(--fxo-primary); /* Defaults to primary */
--fxo-accent-hover: var(--fxo-primary-hover);
}
--fxo-primary drives the header, user bubbles, and launcher. --fxo-accent drives choice buttons, links, and other interactive elements. Set accentColor in your config to override --fxo-accent independently.
Background Colors
:root {
--fxo-bg-opacity: 100%; /* 0% = transparent, 100% = opaque */
--fxo-bg-primary: #ffffff;
--fxo-bg-secondary: #f9fafb;
--fxo-bg-tertiary: #f3f4f6;
}
Text Colors
:root {
--fxo-text-primary: #111827;
--fxo-text-secondary: #6b7280;
--fxo-text-muted: #9ca3af;
--fxo-text-inverse: #ffffff;
}
Message Bubbles
:root {
--fxo-bubble-user-bg: var(--fxo-primary);
--fxo-bubble-user-text: #ffffff;
--fxo-bubble-agent-bg: #f3f4f6;
--fxo-bubble-agent-text: #111827;
}
Typography
:root {
--fxo-font-family: system-ui, -apple-system, sans-serif;
--fxo-font-size-base: 14px;
}
Border Radius
:root {
--fxo-border-radius-base: 8px;
--fxo-border-radius-bubble: 12px;
}
Widget Dimensions
:root {
--fxo-widget-width: 520px;
--fxo-widget-height: 780px;
--fxo-widget-max-height: 90vh;
--fxo-widget-border-radius: 16px;
--fxo-header-height: 64px;
}
Shadows
:root {
--fxo-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--fxo-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
--fxo-shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.15);
--fxo-shadow-widget: 0 5px 40px rgba(0, 0, 0, 0.16);
}
Status Colors
:root {
--fxo-status-online: #22c55e;
--fxo-status-offline: #ef4444;
--fxo-status-error: #ef4444;
--fxo-status-warning: #eab308;
}
Animation Durations
:root {
--fxo-duration-fast: 150ms;
--fxo-duration-normal: 250ms;
--fxo-duration-slow: 350ms;
}
CSS Class Selectors
The widget exposes stable CSS classes for targeting specific elements. These are safe to use in custom CSS.
Widget Container
| Class | Description |
|---|---|
.fxo-widget |
Main widget container |
.fxo-widget--popup |
Popup display mode |
.fxo-widget--sidebar |
Sidebar display mode |
.fxo-widget--fullscreen |
Full-screen display mode |
.fxo-widget--mobile |
Mobile viewport |
.fxo-widget--bottom-left |
Left-positioned launcher |
Size Classes
| Class | Description |
|---|---|
.fxo-widget--size-sm |
Small widget |
.fxo-widget--size-md |
Medium widget |
.fxo-widget--size-lg |
Large widget (default) |
.fxo-widget--size-xl |
Extra-large widget |
.fxo-widget--size-full |
Full-screen widget |
Header
| Class | Description |
|---|---|
.fxo-header |
Header bar |
.fxo-header__avatar |
Avatar image in the header |
.fxo-header__title |
Title text |
.fxo-header__subtitle |
Subtitle text |
.fxo-header__close-btn |
Close button |
.fxo-header__settings-btn |
Settings button |
Messages
| Class | Description |
|---|---|
.fxo-message--user |
User message bubble |
.fxo-message--assistant |
Bot message bubble |
.fxo-message__content |
Message text content |
.fxo-avatar |
Any message avatar |
.fxo-avatar--user |
User avatar |
.fxo-avatar--assistant |
Bot avatar |
.fxo-avatar--liveagent |
Live agent avatar |
Composer
| Class | Description |
|---|---|
.fxo-composer |
Composer area |
.fxo-composer__input |
Text input field |
.fxo-composer__send-btn |
Send button |
.fxo-composer__attachment-btn |
Attachment button |
.fxo-composer__voice-btn |
Voice record button |
Other Elements
| Class | Description |
|---|---|
.fxo-launcher |
Floating launcher button |
.fxo-online-status |
Working hours status banner |
.fxo-choice |
Quick reply / choice buttons |
.fxo-card |
Data cards |
.fxo-attribution |
"Powered by" footer |
Recipes
Custom Font
.fxo-widget {
--fxo-font-family: 'Inter', system-ui, sans-serif;
}
Header Gradient
.fxo-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
Asymmetric Message Bubbles
Give user and bot messages distinct bubble shapes:
.fxo-message--user .fxo-message__content {
border-radius: 20px 20px 4px 20px;
}
.fxo-message--assistant .fxo-message__content {
border-radius: 20px 20px 20px 4px;
}
Larger Popup
.fxo-widget--popup {
--fxo-widget-width: 600px;
--fxo-widget-height: 800px;
}
Semi-Transparent Background
Use the CSS variable for fine-grained control (works with all themes):
.fxo-root {
--fxo-bg-opacity: 80%;
}
Or fully transparent:
.fxo-root {
--fxo-bg-opacity: 0%;
}
You may also want to soften the widget shadow when using transparency:
.fxo-widget {
--fxo-shadow-widget: 0 2px 10px rgba(0, 0, 0, 0.1);
}
backgroundOpacity in the dashboard (0-100) for a no-code approach. The CSS variable gives you the same control from code.
Dark Theme Overrides
[data-theme="dark"] .fxo-widget {
--fxo-bg-primary: #0f172a;
--fxo-bubble-agent-bg: #1e293b;
}
Bigger Launcher with Hover Effect
.fxo-launcher {
width: 70px;
height: 70px;
border-radius: 16px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}
.fxo-launcher:hover {
transform: scale(1.1);
}
Hide Elements
/* Hide attribution */
.fxo-attribution {
display: none;
}
/* Hide the settings button */
.fxo-header__settings-btn {
display: none;
}
/* Hide voice recording */
.fxo-composer__voice-btn {
display: none;
}
Mobile-Only Styling
.fxo-widget--mobile .fxo-header {
padding: 8px 12px;
}
.fxo-widget--mobile {
--fxo-font-size-base: 16px;
}
Complete Example
Combining config and CSS for a fully branded messenger:
FlowXO.init({
connectionId: 'your-connection-id',
config: {
theme: 'auto',
primaryColor: '#4F46E5',
accentColor: '#E85D04',
header: {
title: 'Support Chat',
subtitle: "We're here to help",
iconUrl: 'https://example.com/bot.png'
},
launcher: {
color: '#4F46E5'
},
messages: {
user: { bubbleColor: '#4F46E5' },
assistant: {
bubbleColor: '#EEF2FF',
avatar: {
enabled: true,
iconUrl: 'https://example.com/bot.png'
}
}
},
customCss: `
.fxo-widget {
--fxo-font-family: 'Inter', system-ui, sans-serif;
--fxo-border-radius-bubble: 16px;
}
.fxo-header {
background: linear-gradient(135deg, #4F46E5, #7C3AED);
}
`
}
});
Security Notes
Custom CSS is sanitized. The following are blocked:
@importrulesjavascript:URLsexpression()(IE)-moz-binding(Firefox XBL)behavior:(IE)
External stylesheets ( customCssUrl) must use https://.
Next Steps
- Customizing the Web Messenger — UI-based settings (colors, avatars, features, privacy)
- Installation & Embedding Options — Widget, hosted page, and embed options
- JavaScript API — Programmatic control and user identification