Style the Quests Embed
Colours, fonts, presets, light and dark, --qaid-q tokens, custom CSS and saved themes for @qaiddev/quests-embed.
The quest draws in a shadow root, so your page’s CSS cannot reach it. Style it with the colors option, a preset, a forced light or dark theme, --qaid-q-* tokens in css, or a saved quest theme. unstyled strips every default so only your CSS paints.
The quest draws inside a shadow root, so rules in your page’s stylesheet cannot reach it. Everything below goes in through the embed’s own options. Its tokens are named --qaid-q-*, apart from the thumbs embed’s, so a page running both can style each on its own.
To build a quest and paste its snippet, start with Getting started with quests.
The styling options
import { QaidQuests } from "@qaiddev/quests-embed";
new QaidQuests({
endpoint: "https://qaid.dev/api/quests/responses",
configUrl: "https://qaid.dev/api/quests/YOUR_QUEST_ID/definition",
apiKey: "YOUR_PROJECT_KEY",
container: "#quest-mount",
colors: { accent: "#2D5A3D", error: "#B43E2C", focus: "#D4A24C" },
fontFamily: "'Manrope', system-ui, sans-serif",
preset: "pill",
theme: "light",
});
| Option | Data attribute | Default | Sets |
|---|---|---|---|
colors.accent |
data-positive-color |
#10b981 |
The Next and Submit button, the progress fill, a chosen option’s border, tint and dot, the slider thumb and value, the thank-you tick |
colors.error |
data-negative-color |
#ef4444 |
Validation messages |
colors.focus |
data-marker-color |
#6366f1 |
The focus ring on inputs, buttons, options and the slider |
fontFamily |
data-font-family |
system-ui, -apple-system, sans-serif |
The typeface. The embed loads no fonts, so load a web font in your page first |
fontSize |
data-font-size |
16 |
The base size in pixels |
preset |
data-preset |
"default" |
minimal is flat with square corners and no shadow; pill rounds buttons, options and inputs fully; dense tightens padding |
theme |
data-theme |
"auto" |
"auto" follows the visitor’s system; "light" or "dark" pins it |
css |
data-css-selector |
none | Your own rules and tokens, below |
themeUrl |
data-theme-url |
none | A saved quest theme, below |
unstyled |
data-unstyled |
false |
Strips the look, below |
Text on the button turns black or white, whichever reads better on your accent. The old colour keys positive, negative and marker still work, and the data attributes still use those names.
Change one part with tokens
Tokens are CSS variables. Set them in css, on .qaid-q-root:
css: `
.qaid-q-root {
--qaid-q-card-radius: 0;
--qaid-q-btn-radius: 9999px;
--qaid-q-card-bg: light-dark(#fffdf7, #1b1f1c);
}
`,
light-dark(a, b) gives one value in light mode and another in dark. Every token the embed reads:
/* Card */
--qaid-q-card-bg --qaid-q-card-fg --qaid-q-card-border
--qaid-q-card-radius --qaid-q-card-padding --qaid-q-card-shadow
/* Buttons */
--qaid-q-btn-radius --qaid-q-btn-padding-y --qaid-q-btn-padding-x
--qaid-q-btn-font-size --qaid-q-btn-font-weight
--qaid-q-btn-primary-bg --qaid-q-btn-primary-fg --qaid-q-btn-primary-border
--qaid-q-btn-secondary-bg --qaid-q-btn-secondary-fg
--qaid-q-btn-secondary-border --qaid-q-btn-secondary-hover-bg
/* Choice cards */
--qaid-q-option-bg --qaid-q-option-bg-selected --qaid-q-option-bg-hover
--qaid-q-option-fg --qaid-q-option-border --qaid-q-option-border-selected
--qaid-q-option-border-hover --qaid-q-option-radius --qaid-q-option-padding
/* Radio dot and checkbox */
--qaid-q-marker-bg --qaid-q-marker-bg-selected --qaid-q-marker-border
--qaid-q-marker-icon --qaid-q-marker-radius
/* Text boxes */
--qaid-q-input-bg --qaid-q-input-fg --qaid-q-input-border
--qaid-q-input-radius --qaid-q-input-padding --qaid-q-input-placeholder
/* Everything else */
--qaid-q-muted-fg --qaid-q-progress-track --qaid-q-gap --qaid-q-section-gap
With a script tag, put the CSS in a <style> element and point data-css-selector at it. media="not all" keeps your page from applying it too:
<style id="quest-theme" media="not all">
.qaid-q-root { --qaid-q-card-radius: 0; }
</style>
<script
src="https://unpkg.com/@qaiddev/quests-embed"
defer
data-api-key="YOUR_PROJECT_KEY"
data-endpoint="https://qaid.dev/api/quests/responses"
data-config-url="https://qaid.dev/api/quests/YOUR_QUEST_ID/definition"
data-css-selector="#quest-theme"
></script>
In a JSON config block the key is cssSelector.
Use a saved quest theme
A theme made in the dashboard is a hosted document of tokens, CSS and settings. Customize writes its URL into your snippet as themeUrl; see Design and publish a quest theme.
The embed fetches the theme alongside the quest. If the fetch fails, the quest still draws, with the defaults. themeDocument takes the same document as an object, for a server that fetched it already.
Later layers win. The built-in stylesheet comes first, then the theme’s tokens, the preset, the theme’s CSS, and last your page’s css. A preset, theme, unstyled, colour or font set on the page replaces the saved theme’s value.
Take over completely
With unstyled: true, you draw every part yourself. Style these classes:
/* Frame */
.qaid-q-card, .qaid-q-header, .qaid-q-title, .qaid-q-description,
.qaid-q-step-counter, .qaid-q-progress, .qaid-q-progress-fill {}
/* One question */
.qaid-q-step, .qaid-q-label, .qaid-q-error {}
.qaid-q-input, .qaid-q-textarea, .qaid-q-currency, .qaid-q-currency-prefix,
.qaid-q-range-wrap, .qaid-q-range, .qaid-q-range-value {}
.qaid-q-options, .qaid-q-option, .qaid-q-option.qaid-q-selected,
.qaid-q-option-marker, .qaid-q-option-body, .qaid-q-option-label, .qaid-q-option-desc {}
/* Buttons and the end screen */
.qaid-q-footer, .qaid-q-btn, .qaid-q-btn-primary, .qaid-q-btn-secondary {}
.qaid-q-done, .qaid-q-done-icon, .qaid-q-done-title, .qaid-q-done-message, .qaid-q-saving {}
/* The retry screen when sending fails (1.5.3 or later) */
.qaid-q-submit-error, .qaid-q-submit-error-title,
.qaid-q-submit-error-message, .qaid-q-submit-error-actions {}
The same classes work without unstyled, for a change no token covers.
Fit an inline form
Inline, the quest takes the width of its container. Give the container a fixed height and the card fills it: the body scrolls inside, with a fade and a cue when more is below. Under about 360px of height, image choices and gaps shrink to fit.
progressPosition: "bottom"moves the step counter and bar into the footer, beside the buttons, so the question sits higher. The quest’s own Position setting does the same from the dashboard; the page option wins.- Hide Header and Hide Progress in the quest editor remove the title row and the counter. A one-question quest never shows progress.
modalWidth,backdropOpacityandzIndexdo nothing inline.
Preview inside a page builder
In an editor’s preview pane, set autoFocus: false so the first step does not pull focus from the editor, and animate: false so the step does not slide in on every rebuild. To show edits, call quest.update(newQuestionnaire) instead of building a new embed; it redraws in place and never moves focus.