Summary
When the Formbricks survey modal initializes, surveys.umd.cjs injects a <style id="formbricks__css"> tag into document.head that contains an unscoped @layer properties block. This block resets ~30 Tailwind CSS custom properties (--tw-shadow, --tw-ring-*, --tw-border-style, --tw-translate-*, etc.) to initial on every element on the host page via a *, :before, :after, ::backdrop selector.
The result: opening a Formbricks survey modal visibly breaks shadows, rings, transforms, borders, and other Tailwind-based styles across the entire host page for the remainder of the session.
Root cause
Inside the injected formbricks__css style element, the CSS is structured as:
/* ✅ Correctly scoped — only affects #fbjs elements */
#fbjs *, #fbjs :before, #fbjs :after {
box-sizing: border-box;
border-width: 0;
/* ... Tailwind preflight reset ... */
}
/* ❌ NOT scoped — affects the entire host page */
@layer properties {
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or
((-moz-orient: inline) and (not (color: rgb(from red r g b)))) {
*, :before, :after, ::backdrop {
--tw-rotate-x: initial;
--tw-rotate-y: initial;
--tw-skew-x: initial;
--tw-skew-y: initial;
--tw-border-style: solid;
--tw-shadow: 0 0 #0000;
--tw-shadow-color: initial;
--tw-ring-color: initial;
--tw-ring-shadow: 0 0 #0000;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-offset-shadow: 0 0 #0000;
--tw-outline-style: solid;
/* ~20 more --tw-* properties... */
}
}
}
The key issue: CSS @layer at-rules cannot be scoped by a surrounding selector. Even though this block lives inside a style element alongside #fbjs-prefixed rules, the @layer properties block is globally scoped by the CSS spec. Any --tw-* custom property values the host page has set (via its own Tailwind v4 @layer properties block) are wiped out and replaced with initial / zero values on every element.
You can verify this in the current surveys.umd.cjs by searching for @layer properties — the selector inside is bare *, not #fbjs *.
Reproduction
- Integrate Formbricks into any page using Tailwind CSS v4 with shadows, rings, or transforms.
- Trigger a survey modal.
- Observe that
shadow-*, ring-*, ring-offset-*, rotate-*, and other utilities are broken across the entire host page after the modal initializes — including elements completely outside the modal.
Tailwind v4 utilities depend on --tw-* custom properties being set at the utility class level. The Formbricks @layer properties block resets these to initial, so computed styles collapse.
Impact
Any host site using Tailwind CSS v4 is affected. The @layer scoping issue is a CSS spec constraint, so all browsers are affected.
Suggested fixes
The @layer properties block is a Tailwind v4 internal browser-compatibility fallback for browsers that do not support @property. It should not be included in the host-page stylesheet because:
- It is only needed inside the survey component rendering context.
- It cannot be safely scoped to
#fbjs — @layer ignores outer selector context by spec.
Option A — Shadow DOM (preferred): Move all Formbricks survey styles into a Shadow DOM. Styles inside a shadow root (including @layer and * selectors) do not bleed into the host document. This is the only mechanism that provides true CSS encapsulation.
Option B — Strip @layer properties from the injected stylesheet: Remove this block from formbricks__css entirely. Surveys render correctly in all modern browsers without it — the @property declarations already present in the same style element serve the same browser compat purpose.
Note: Attempting to scope * to #fbjs * inside @layer will not work — @layer ignores outer selector context by spec.
Environment
- SDK:
https://app.formbricks.com/js/formbricks.umd.cjs
- Surveys bundle:
https://app.formbricks.com/js/surveys.umd.cjs (769 KB, analyzed April 2026)
- Host page framework: Tailwind CSS v4
- Affected browsers: all (CSS spec behavior, not a browser bug)
Summary
When the Formbricks survey modal initializes,
surveys.umd.cjsinjects a<style id="formbricks__css">tag intodocument.headthat contains an unscoped@layer propertiesblock. This block resets ~30 Tailwind CSS custom properties (--tw-shadow,--tw-ring-*,--tw-border-style,--tw-translate-*, etc.) toinitialon every element on the host page via a*, :before, :after, ::backdropselector.The result: opening a Formbricks survey modal visibly breaks shadows, rings, transforms, borders, and other Tailwind-based styles across the entire host page for the remainder of the session.
Root cause
Inside the injected
formbricks__cssstyle element, the CSS is structured as:The key issue: CSS
@layerat-rules cannot be scoped by a surrounding selector. Even though this block lives inside a style element alongside#fbjs-prefixed rules, the@layer propertiesblock is globally scoped by the CSS spec. Any--tw-*custom property values the host page has set (via its own Tailwind v4@layer propertiesblock) are wiped out and replaced withinitial/ zero values on every element.You can verify this in the current
surveys.umd.cjsby searching for@layer properties— the selector inside is bare*, not#fbjs *.Reproduction
shadow-*,ring-*,ring-offset-*,rotate-*, and other utilities are broken across the entire host page after the modal initializes — including elements completely outside the modal.Tailwind v4 utilities depend on
--tw-*custom properties being set at the utility class level. The Formbricks@layer propertiesblock resets these toinitial, so computed styles collapse.Impact
Any host site using Tailwind CSS v4 is affected. The
@layerscoping issue is a CSS spec constraint, so all browsers are affected.Suggested fixes
The
@layer propertiesblock is a Tailwind v4 internal browser-compatibility fallback for browsers that do not support@property. It should not be included in the host-page stylesheet because:#fbjs—@layerignores outer selector context by spec.Option A — Shadow DOM (preferred): Move all Formbricks survey styles into a Shadow DOM. Styles inside a shadow root (including
@layerand*selectors) do not bleed into the host document. This is the only mechanism that provides true CSS encapsulation.Option B — Strip
@layer propertiesfrom the injected stylesheet: Remove this block fromformbricks__cssentirely. Surveys render correctly in all modern browsers without it — the@propertydeclarations already present in the same style element serve the same browser compat purpose.Note: Attempting to scope
*to#fbjs *inside@layerwill not work —@layerignores outer selector context by spec.Environment
https://app.formbricks.com/js/formbricks.umd.cjshttps://app.formbricks.com/js/surveys.umd.cjs(769 KB, analyzed April 2026)