Styling the Feedback Embed: CSS, Tokens and Dark Mode
How your CSS reaches the feedback widget, every class it draws, the tokens it reads, dark mode, the phone sheet and the thank-you screen.
Styles meet the widget only from inside its own shadow roots, so hand them over as an option rather than a page stylesheet. Every class and token it has is listed here. The box, thank-you screen included, takes its light or dark look from your page.
This is the reference for styling the feedback widget. For one task at a time, see colours, button styles, icons and presets.
Add your own CSS
The widget draws into two shadow roots. One holds the buttons. The other, made the first time it is needed, holds everything that covers the page: the targeting marks, the message box, the markup editor and the video controls. Your page’s stylesheet reaches neither.
The CSS you pass is copied into both roots, after the widget’s own sheet. So a rule of yours with the same selector as a built-in one wins: your button.qaid-btn-submit beats the widget’s button.qaid-btn-submit.
| You install with | Pass the CSS as |
|---|---|
| JavaScript | css: "…" |
| A JSON config block | "cssSelector": "#qaid-theme", naming a <style> element on the page |
| The script tag | data-css-selector="#qaid-theme", the same |
<style id="qaid-theme" media="not all">
.qaid-modal-box { border-radius: 6px; }
</style>
<script
src="https://unpkg.com/@qaiddev/thumbs-embed/dist/embed.js"
defer
data-api-key="YOUR_PROJECT_KEY"
data-endpoint="https://qaid.dev/api/feedback"
data-css-selector="#qaid-theme"
></script>
The widget reads the block’s text once, when it starts. media="not all" stops your page from applying the same rules to itself. The Customize page builds exactly this; see The Embed Customizer.
Know the class names
| Selector | What it is |
|---|---|
.qaid-buttons |
The row, or column, of buttons |
button.qaid-btn |
A default button. With buttonClass set it is .qaid-btn-structural plus your class |
.qaid-btn-up, .qaid-btn-down, .qaid-btn-feedback, .qaid-btn-record |
Thumbs up, thumbs down, the single button, the record button |
.qaid-dismiss-btn, .qaid-tooltip-text |
The × and the tooltip |
.qaid-backdrop |
The dimmed page behind the box |
.qaid-modal-container |
The placed wrapper, with .qaid-below or .qaid-above |
.qaid-modal-arrow, .qaid-modal-box |
The point toward the picked element, and the card |
.qaid-modal-header, .qaid-modal-header-text |
The header row and its text column |
button.qaid-type-toggle |
The up/down badge, with .qaid-type-up or .qaid-type-down |
.qaid-type-static |
The badge in single-button mode |
.qaid-modal-title, .qaid-modal-subtitle |
The heading and the line under it |
.qaid-textarea, .qaid-btn-row, button.qaid-btn-submit |
The field, the button row and its one button |
.qaid-bottom-sheet, .qaid-bottom-sheet-content, .qaid-bottom-sheet-handle |
The phone layout |
.qaid-confirm, .qaid-confirm-icon, .qaid-confirm-title, .qaid-confirm-message, .qaid-confirm-close |
The thank-you screen. The error screen adds .qaid-confirm-error |
.qaid-selected-marker, .qaid-highlight-box, .qaid-vignette |
Targeting marks |
.qaid-annotate and .qaid-annotate-* |
The screenshot markup editor |
.qaid-video-preview-box, .qaid-recording-indicator, .qaid-video-error |
Video review, the pill shown while recording, and the line shown when an upload fails |
Use a setting before a rule
| Option | Script attribute | Default | Notes |
|---|---|---|---|
modalWidth |
data-modal-width |
400 |
Pixels. Ignored on phones |
backdropOpacity |
data-backdrop-opacity |
0.3 |
Written as an inline style, so a .qaid-backdrop rule needs !important |
fontFamily |
data-font-family |
system-ui, -apple-system, sans-serif |
The box, sheet, editor and video review |
fontSize |
data-font-size |
16 |
Pixels. Every text size in the box, sheet, tooltip, editor and video review is a multiple of it. Needs thumbs-embed 1.8.0 or later |
buttonSize |
data-button-size |
medium |
36, 48 or 64 pixel buttons |
colors |
data-positive-color and friends |
See Brand color matching |
Read and set the tokens
| Token | Comes from | Used for |
|---|---|---|
--qaid-positive, --qaid-negative |
colors |
Hover fills, targeting marks, the up/down badge |
--qaid-marker |
colors.marker |
Submit button, focus rings, the picked-element ring |
--qaid-marker-text |
Black or white, worked out from the marker | Text on marker-coloured buttons |
--qaid-btn-size, --qaid-icon-size |
buttonSize |
Default button and icon size |
--qaid-modal-width, --qaid-font-family, --qaid-font-size |
The options above | The box |
--qaid-hover-up-bg, --qaid-hover-up-color, --qaid-hover-down-bg, --qaid-hover-down-color |
Declared on button.qaid-btn |
Default hover fill and icon colour |
--qaid-success |
Nothing; #22c55e |
The thank-you check mark |
--qaid-error |
Nothing; #dc2626 |
The error screen’s mark |
--qaid-text, --qaid-text-muted |
Nothing; dark greys on a light box, light greys on a dark one | Thank-you and error title and message |
--qaid-primary |
Nothing; #6365f1 |
Focus ring on the thank-you title |
Change the first five rows through the options: the widget writes them onto each of its containers as inline styles. A button.qaid-btn { … } rule of yours can change the hover tokens, which live in the default button rule. Nothing sets the last five, so set them on :host, which is how a rule inside a shadow root names the root’s own element.
Restyle the message box
One theme, a flat paper card. Click a button to open it, send a message to see the thank-you screen.
.qaid-modal-box,
.qaid-bottom-sheet-content {
background: #fffdf7;
border: 2px solid #1c1917;
border-radius: 4px;
box-shadow: 6px 6px 0 #1c1917;
}
/* The arrow is a border: one rule for a box below the element, one for above. */
.qaid-modal-container.qaid-below .qaid-modal-arrow { border-bottom-color: #1c1917; }
.qaid-modal-container.qaid-above .qaid-modal-arrow { border-top-color: #1c1917; }
.qaid-modal-title { color: #1c1917; font-family: Georgia, serif; }
.qaid-modal-subtitle { color: #57534e; }
.qaid-textarea { background: #fff; color: #1c1917; border: 2px solid #1c1917; border-radius: 0; }
button.qaid-btn-submit { border-radius: 0; }
:host { --qaid-text: #1c1917; --qaid-text-muted: #57534e; --qaid-success: #1c1917; }
Pair it with colors: { marker: "#1c1917" } for the dark submit button. The widget places the box as if it were about 280 pixels tall. Heavy padding can push it past the edge of a short window, where it scrolls inside itself.
Force light or dark
The box, the sheet, the video review and the editor’s toolbar use the CSS light-dark() function. It follows the color-scheme of your page, not the visitor’s system on its own.
| Your page declares | The widget shows |
|---|---|
| Nothing | Light, always |
color-scheme: light dark |
Light or dark, following the system |
color-scheme: dark |
Dark, always |
To pin the widget whatever the page says, add :host { color-scheme: dark; } (or light) to your CSS.
The thank-you and error screens switch too, in thumbs-embed 1.8.0 or later. Setting --qaid-text or --qaid-text-muted fixes their colour in both modes.
Style the phone sheet
In a window under 640 pixels wide, the box opens as a sheet along the bottom: .qaid-bottom-sheet holding .qaid-bottom-sheet-content, which starts with the grab bar .qaid-bottom-sheet-handle. It has no arrow, ignores modalWidth, and pads itself clear of the phone’s home bar. Inside, the header, field and button keep their usual classes. Wherever you style .qaid-modal-box, style .qaid-bottom-sheet-content too.
Style the thank-you screen
Once the message is sent, the card’s contents are swapped for .qaid-confirm: a round check mark (.qaid-confirm-icon, filled with --qaid-success), a title, a message, and a Close button. That button also carries button.qaid-btn-submit, so your submit rules reach it.
The screen shows once the server takes the message. Set hideConfirmation: true (data-hide-confirmation="true") to close the box straight away instead. The words come from text.confirmationTitle, confirmationMessage and confirmationClose; see Text customization.
If the server refuses the message, or the network fails, the same card shows with .qaid-confirm-error added: a red mark filled with --qaid-error, the errorTitle and errorMessage text, and the same Close button. It shows even with hideConfirmation.
For visitors whose system asks for less motion, the widget switches off every transition and animation, yours included. Custom button styles has more.