Skip to main content
Sprig In-Product Studies can follow the respondent’s system light or dark appearance automatically. This page covers how dark mode works, how it interacts with your custom CSS, and the patterns we recommend for keeping a study readable in both modes.
Availability: Default CSS dark mode shipped in Web SDK v2.49.0, and studies rendered in a mobile SDK need a version built against it: see Minimum SDK versions below.Dark mode is enabled per Sprig Product and is not on by default. Reach out to your Customer Success Manager or support@sprig.com to have it turned on. A self-serve setting in the dashboard is coming soon!

How it works

Sprig loads a second stylesheet that responds to the respondent’s operating system or browser appearance setting via the standard CSS media query:
There is no separate “dark theme” for you to configure and no toggle inside the survey. If a respondent’s device or browser is set to dark, the study renders dark; if it’s set to light, the study renders light. The switch is instant and happens on the respondent’s device/browser. Sprig’s styles are built on CSS custom properties (variables). The light values are declared once, and the dark stylesheet re-declares the same variable names with dark values. Every Sprig selector reads from those variables, so changing one variable updates every place that color is used.

Load order and specificity

How the CSS is applied:
  1. Your custom CSS is injected after Sprig’s stylesheets. At equal specificity, your rules win. You do not need !important for ordinary overrides.
  2. Sprig’s dark values are declared on :root, not html. :root has higher specificity than html, so a variable you set on html will apply in light mode but be overridden by Sprig in dark mode.
The commented reference block in the CSS editor is light-mode only. The default CSS shown in Settings > Surveys > Look & Feel > CSS is a snapshot of Sprig’s selectors with hardcoded light colors. It does not list the CSS variables or the dark palette. Use the variable reference below instead when you’re working on dark mode.

Choosing an approach

You don’t have to use CSS variables. Variables are a convenience: because every Sprig selector reads from them, changing one value updates everywhere that color is used. But a plain @media (prefers-color-scheme: dark) block with ordinary selector overrides works exactly as well, and is often clearer if you’re only touching a handful of elements. Use whichever fits your stylesheet.

Approach 1: Do nothing (color-free customizations)

If your custom CSS only changes layout, spacing, typography, or border radius, it already works in both modes. Sprig’s colors keep flowing through the variables.
Any hardcoded color you add is a dark mode bug waiting to happen. A rule like .ul-question { color: #1f2937; } applies in both modes, which means near-black text on Sprig’s near-black dark card. If you set a foreground color, set the matching background color too, or move both into variables.

Approach 2: Override selectors directly

No variables involved. Write your light-mode rules as usual, then re-declare whatever needs to change inside a @media (prefers-color-scheme: dark) block. Your custom CSS is injected after Sprig’s, so at equal specificity your rules win in both modes.
Direct overrides don’t propagate. A variable you change is picked up everywhere Sprig uses it; a selector you override only affects that selector. If you restyle .ul-question for dark mode, you still need to handle .ul-caption, .choice, the number rows, and anything else you’ve given a color to. Step through every question type in the preview before saving.

Approach 3: Override Sprig’s variables

The lowest-effort way to brand both modes. Set Sprig’s own variable names on :root for light, then re-declare the ones that need to change inside a dark media query. Every Sprig selector picks the new values up automatically.

Approach 4: Define your own tokens

If your company already maintains light/dark color pairs, declare them all up front, point a set of “active” tokens at the light values, and remap only the active tokens in the dark block. Your selectors then reference the active tokens and never need duplicating.

CSS variable reference

These are the variables Sprig’s stylesheets read from, with the default value in each mode. Override any of them on :root.
This table reflects Web SDK v2.49.0. Sprig may add variables in later versions; anything not listed here should be overridden by selector instead.
Core surfaces and text Buttons and progress Choice and selection elements Question-type specific

Conversational UI

Conversational studies load an additional dark stylesheet with its own variables for the chat transcript and inputs. The most commonly overridden: Override these the same way, inside a @media (prefers-color-scheme: dark) block on :root.

Common issues

You most likely declared your variables on html instead of :root. Sprig’s dark values are on :root, which has higher specificity, so it wins regardless of source order. Change your selector to :root.
You have a hardcoded foreground color with no matching background, or vice versa. Search your CSS for any literal hex value on a color, background, or border-color property and either move it into a variable pair or wrap the dark variant in a @media (prefers-color-scheme: dark) block.
Something in the card’s ancestry still has a light background. Reset the wrappers to transparent so the host page shows through:
Some Sprig icons are inline SVG data URIs with a fixed stroke color. Sprig’s dark stylesheet replaces the affected ones, but if you’ve overridden a background shorthand you may have wiped the replacement. Set background-color rather than background, or re-declare the background-image in your dark block.
Confirm three things: dark mode has been enabled for your Sprig Product (it is off by default; contact your Customer Success Manager or support@sprig.com), you’re on Web SDK v2.49.0 or later or a mobile SDK version built against it (see Minimum SDK versions), and the test device’s OS appearance is actually set to Dark.Enablement is per Product, not per environment: a Product’s development and production environments share one setting. If dark mode works in one place and not another, check whether you’re comparing two different Products rather than two environments of the same one. The in-editor preview reflects your browser’s current appearance setting.

Testing your CSS

Because custom CSS applies to all studies in a product, including active ones, test both modes before saving to production.
  1. Work in a development environment first, then copy the finished CSS into production.
  2. Toggle your OS appearance (macOS: System Settings > Appearance; Windows: Settings > Personalization > Colors) and re-check the preview panel.
  3. In Chrome DevTools you can force the media query without changing your OS: open the Command Menu (Cmd/Ctrl + Shift + P), run Show Rendering, and set Emulate CSS media feature prefers-color-scheme.
  4. Step through every question type in the preview, not just the first card. Matrix, NPS, Rank Order, and Open Text have the most mode-specific styling.
  5. Check contrast. Brand colors tuned for a white background are frequently too dark on #1c1c1e; most design systems ship a lightened variant for dark surfaces for exactly this reason.

Mobile SDKs

Studies rendered in the iOS, Android, React Native, and Flutter SDKs use the same web stylesheets inside a web view, so everything on this page applies there as well. Native light/dark support (the SDK letting the web view render dark at all) landed earlier than the default CSS work, which is why some customers were already shipping their own dark mode CSS before v2.49.0. The mobile SDKs also expose APIs to force a study into light or dark regardless of the device setting — see the SDK changelogs.

Minimum SDK versions

These are the first mobile SDK releases built against Web SDK v2.49.0, and therefore the first to include the default CSS dark mode styles.
For the full list of selectors and non-color customization options, see Styling Studies with Custom CSS.