Plans. On Formbricks Cloud, Custom CSS is part of the Scale plan. Self-hosted instances get it on
every plan, without a license. If a Cloud organization leaves the Scale plan, its saved CSS keeps
applying, but it can only be cleared, not changed.
Where To Add CSS
There are two places, and they add up: survey CSS is applied on top of workspace CSS, never instead of it.
Survey CSS follows the survey’s other style overrides. It applies only while the workspace allows them (Enable custom styling in Appearance) and the survey uses them (Add custom styles in its Styling tab). With either one off, respondents get the workspace CSS only, and the survey’s Custom CSS card is greyed out like the other styling cards. Nothing is deleted: the survey’s CSS applies again once both are on. The API and MCP tools can set survey CSS either way.
Each level has two fields, switched with the Light / Dark toggle at the top of the styling editor:
- Base CSS (Light selected) applies in light and dark mode.
- Dark CSS (Dark selected) applies only when the survey is shown dark, on top of the base CSS. Leave it empty and the base CSS alone is used in dark mode.
1
Open the Custom CSS card
In the workspace Appearance settings or in a survey’s Styling tab.
2
Pick the field
Select Light to edit the base CSS or Dark to edit the dark CSS.
3
Write or upload your CSS
Type into the field, or use Upload .css to load a
.css file. The upload replaces the content of the field that is currently selected; the other field is not touched, and undo brings the replaced CSS back. Type [ or --fb to get suggestions for the stable hooks, states and variables. Tab indents; press Esc, then Tab, to leave the field.4
Check the preview, then save
The preview updates shortly after you stop typing. Lines with an error get a red line number, and lines with a removed rule an amber one; the list under the field says what Formbricks removed or rejected, and why. Survey CSS is saved with the survey. Workspace CSS is saved with the Save button of the Appearance page, together with the theme, and changes every survey in the workspace. Restore previous version loads the workspace CSS from before the last save.
Custom CSS styles the card. Head scripts are for scripts, tags and page-level styles. If a self-hosted
link survey also has Custom Head Scripts with styles, both
apply, and on the survey card your Custom CSS wins.
How Your CSS Is Applied
Everything Is Scoped To The Survey
Every rule is scoped to the survey root,#fbjs. You do not need to write #fbjs yourself: Formbricks adds it to every selector that lacks it.
:root,htmlandbodymean the survey root.:root { --brand: #1f5f8b; }sets a variable on the survey, andbody { font-family: … }sets the survey’s font.- Your CSS never reaches the page around the survey, and rules that try to (
#fbjs + .x,#fbjs ~ .x,:root:has(~ .x),:host) are removed. Relative:has()such as:has(> .x)or:has(+ .x)works on any element inside the survey. - Open dropdown lists render in their own survey root, so your rules and variables reach them too.
Base And Dark
The survey’s appearance is set by the app or page that shows it (light by default). In dark mode, the survey root carriesdata-appearance="dark".
- Rules in the Dark CSS field are scoped to
#fbjs[data-appearance="dark"]for you. Write them like base rules:[data-fb-part="card"] { background: #0f1b24; }, and:root { … }sets variables for dark mode only. - In the Base CSS field you can also write dark rules yourself, starting with
#fbjs[data-appearance="dark"]. - Anything in base CSS also applies in dark mode, including colors. A base rule that sets a text or background color replaces the dark color Formbricks would otherwise derive, so set the dark value in Dark CSS. The editor reminds you when base CSS sets colors and the dark field is empty.
Nesting
CSS nesting is supported. It is flattened when you save, so it works in every supported browser.Precedence
Your declarations are made!important automatically and placed in their own cascade layers, so they win over the built-in survey styles and over the CSS of the page that shows the survey. You never need to write !important yourself.
The sources apply in this order. Where two style the same thing, the later one wins, so each source overrides everything above it:
Inside one field the normal cascade applies: the more specific selector wins, then the later rule.
Two consequences worth knowing:
- In dark mode, survey base CSS wins over workspace dark CSS. If a survey’s base CSS sets colors, give that survey its own dark CSS too.
- When your CSS sets a property, the theme editor can no longer change it. If changing a color in the theme editor seems to do nothing, check your Custom CSS.
Stable Hooks
Target survey parts through theirdata-fb-part attribute. These names are a supported contract and stay stable across releases.
The file upload area and Cal.com booking embeds have no part hooks of their own; style them through the variables. Their headline, description, error and buttons are hooked like everywhere else.
States
Interactive states are on the hooked element itself, so:hover, :active and :focus-visible work directly on buttons, fields and the dropdown. A choice row is a label around a native control, so its state is read from the control inside it with :has().
To style selected choices in lists and in dropdowns with one rule, combine both forms:
[data-fb-part="option"]:is([aria-checked="true"], [data-checked="true"]).
Variables
The theme editor writes its values to--fb-* variables on the survey root. Setting them in Custom CSS is often the shortest way to restyle a whole group of elements, including the ones without hooks.
--acme-ink, and use them in your rules.
Examples
Option Label And Control
If you give
option-control a background, also give it one for the checked state. Your rule replaces the
built-in fill of a checked checkbox, which would otherwise disappear.Headline
Headlines can contain formatted text (bold, links, lists). A font family, size, weight or color set on the hook reaches every part of it, and bold text stays bold.--fb-element-headline-*) work as well. The same applies to descriptions, with the --fb-element-description-* variables.
Primary Button
Focus
Keep a visible focus indicator. Use a transparent outline together with abox-shadow ring, rather than outline: none: Windows high-contrast mode drops shadows but shows the outline, so the ring never disappears.
Dark Rules
With Dark selected, add only what changes in dark mode:@media (prefers-color-scheme: dark)follows the device, not the survey. A survey your app shows light would still get the dark rules.- Theme classes of your own page, such as
html.dark …. The survey cannot see them, andhtmlmeans the survey root here. light-dark()needs Safari 17.5 or later, above the supported baseline.color-scheme: darkon the root can paint the transparent survey background in mobile apps.
Migrating From Qualtrics
Qualtrics stylesheets do not work unchanged. Their selectors (.QuestionText, #NextButton, …) match nothing in a Formbricks survey. Formbricks accepts them without a warning, but they have no effect until you port them. Move each rule to the matching hook:
Before, written for Qualtrics:
- The
@importis gone. Formbricks removes it, and it would only produce a warning. See Fonts. :rootandbodystay, because they mean the survey root.- Every Qualtrics selector was replaced by a hook. Nothing was renamed automatically.
Fonts
Custom CSS cannot load fonts.@import, @font-face and every url() are removed, so name fonts that are already available and always end with a fallback:
- Website & app surveys can use any font your page already loads.
- Link surveys and mobile apps only have the fonts installed on the respondent’s device, so the fallback is what most respondents see.
What Formbricks Removes Or Rejects
Formbricks checks your CSS when you preview and when you save. Removed with a warning. The save succeeds, and the rest of your CSS applies:
Define
@keyframes in the same field as the rules that use them.
Rejected. Nothing is saved and the previously saved CSS stays in place:
- Syntax errors, reported with line and column. This includes a block left without its closing
}, which browsers would quietly close at the end and nest every rule after it inside. - CSS over the size limit, or over one of the complexity limits below.
- Anything Formbricks cannot process safely.
Limits
Sizes are counted in bytes of UTF-8 text, so most characters count as one byte. The processed output adds scoping to every selector, so CSS close to the size limit that consists of many short rules can exceed the output limit. At most 50 warnings are listed per check; anything beyond that is still removed.
The editor only mentions sizes when CSS goes over a limit, with the size it counted and the limit.
Two notes do not remove anything: Unknown property (for example a typo like
colr) and Invalid value (for example color: notacolor). The declaration stays, but browsers ignore it, so it has no effect.
Responsive Rules
@media width queries read the width of the page, not of the survey. A website survey shown as a 400 px pop-up on a desktop page matches desktop breakpoints, and the editor preview can match different breakpoints than the live page. Use width queries for page-level layout only, and keep survey styles that must hold at any size outside them.
Browser And App Support
Custom CSS works on the same browsers as Formbricks surveys:
Write CSS those browsers understand. Nesting is flattened for you, but newer features such as
light-dark() are not.
Link surveys and website & app surveys get your CSS as soon as it is saved. Mobile apps need an SDK version with Custom CSS support. Older SDK versions show surveys without any Custom CSS, never with only part of it. See SDK Compatibility for the versions.
API
The Management API v3 reads and writes Custom CSS too:customCss on surveys, and the workspace’s Custom CSS under /workspaces/{workspaceId}/custom-css. Both use the same checks, warnings and limits as the editor.
Troubleshooting
A rule has no effect- Check the warnings under the field. The rule may have been removed.
- Make sure it targets a hook, a state or a variable from this page, not a generated class name.
- For headlines and descriptions, set the typography variables instead of
font-sizeorcolordirectly.
- Base CSS also applies in dark mode. Add the dark colors to Dark CSS.
- In dark mode, survey base CSS beats workspace dark CSS. Add survey dark CSS.
- Saved changes can take up to an hour to reach respondents, and an open survey keeps its styling until it is finished.
- In a mobile app, check that the app uses an SDK version with Custom CSS support.