Styling

The package ships with minimal default styles. To use them:

import 'react-feedback-surveys/index.css';

CSS Variables

You can override colors and fonts via CSS variables:

:root {
  /* Main text color for headings and body text */
  --ft-color-text: 30 8% 14%;

  /* Background color for survey widgets */
  --ft-color-bg: 0 0% 100%;

  /* Muted text color for labels and secondary content */
  --ft-color-muted: 222 11% 46%;

  /* Error color for validation messages */
  --ft-color-error: 32 95% 44%;

  /* Border color for inputs and containers */
  --ft-color-border: 214 14% 83%;

  /* Outline color for focused interactive elements */
  --ft-color-outline: 218 14% 65%;

  /* Shadow color for depth and elevation effects */
  --ft-color-shadow: 0 0% 0%;

  /* Background color for input controls and buttons */
  --ft-color-control: 214 20% 96%;

  /* Z-index for popup overlay positioning */
  --ft-popup-z-index: 49;

  /* Padding for Surface component container (desktop) */
  --ft-surface-padding: 24px;

  /* Padding for Surface component container on mobile devices (max-width: 400px) */
  --ft-surface-padding-mobile: 20px;
}

/* Use with hsl() function: */
/* color: hsl(var(--ft-color-text)); */
/* background: hsl(var(--ft-color-bg)); */
/* box-shadow: 0 0 10px hsl(var(--ft-color-shadow) / 20%); */

Dark Theme Example

The library uses CSS variables for all colors, making it easy to implement custom themes including dark mode. The library itself is theme-agnostic - you control how to override the variables.

Example dark theme color palette:

Here's an example of dark theme colors that work well with the survey components:

/* Example: Class-based dark theme */
.dark {
  --ft-color-text: 210 11% 88%;
  --ft-color-bg: 220 13% 13%;
  --ft-color-muted: 214 10% 60%;
  --ft-color-error: 14 90% 62%;
  --ft-color-border: 217 10% 28%;
  --ft-color-outline: 216 12% 45%;
  --ft-color-shadow: 0 0% 0%;
  --ft-color-control: 218 12% 19%;
}

/* Alternative: Using media query */
@media (prefers-color-scheme: dark) {
  :root {
    --ft-color-text: 210 11% 88%;
    --ft-color-bg: 220 13% 13%;
    /* ... other variables */
  }
}

/* Alternative: Data attribute based */
[data-theme="dark"] {
  --ft-color-text: 210 11% 88%;
  --ft-color-bg: 220 13% 13%;
  /* ... other variables */
}

Implementation example with React:

import { CSAT5Survey } from 'react-feedback-surveys';
import 'react-feedback-surveys/index.css';
import { useEffect } from 'react';

function App() {
  useEffect(() => {
    // Example: Apply theme based on system preference
    const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;

    if (isDarkMode) {
      document.documentElement.classList.add('dark');
    }

    // Listen for system preference changes
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    const handleChange = (e: MediaQueryListEvent) => {
      document.documentElement.classList.toggle('dark', e.matches);
    };

    mediaQuery.addEventListener('change', handleChange);
    return () => mediaQuery.removeEventListener('change', handleChange);
  }, []);

  return (
    <CSAT5Survey
      scaleStyle="emoji"
      question="How satisfied are you with our product?"
      onScoreSubmit={({ value }) => console.log('Score:', value)}
    />
  );
}

Manual theme toggle:

// Toggle between light and dark
function toggleTheme() {
  document.documentElement.classList.toggle('dark');
}

// Set specific theme
function setTheme(theme: 'light' | 'dark') {
  document.documentElement.classList.toggle('dark', theme === 'dark');
}

Notes:

  • The library only uses CSS variables - how you define them is up to you
  • Choose any approach: class-based, data attributes, media queries, or CSS-in-JS
  • The example colors provide WCAG AA compliant contrast ratios
  • Emoji and icon colors remain unchanged regardless of theme

Or wrap the survey in your own class and target the generated markup.

For deeper customization strategies, see the section below.

Custom Classes

All widgets accept a classNames prop with two optional groups: base (outer shell) and scale (the interactive rating UI). Pass your own class names to override styles without relying on internal selectors.

When is this useful?

  • Apply your design system spacing, typography or colors
  • Adjust layout (e.g., make the scale full-width, change gaps)
  • Restyle scale items (buttons, icons, numbers) consistently

Reference: available keys

Comparison table
KeyApplies to
base.baseThe outer widget container
base.headHeader row containing title and close button
base.titleThe heading that shows main/feedback/success text
base.bodyMain content region (rating scale, feedback form or success)
base.closeClose button
scale.baseContainer around the scale style
scale.listWrapper for the interactive items (emoji/stars/numbers)
scale.buttonEach clickable item in the scale
scale.iconIcon inside a scale button (emoji, stars)
scale.scoreNumber inside a scale button (for numeric variants)
scale.labelsLeft/Right labels displayed under the scale

Example: customizing a CSAT5Survey widget

import { CSAT5Survey } from 'react-feedback-surveys';
import 'react-feedback-surveys/index.css';

<CSAT5Survey
  classNames={{
    base: {
      base: 'my-survey-base',
      body: 'my-survey-body',
    },
    scale: {
      list: 'my-scale-list',
      button: 'my-scale-button',
      score: 'my-scale-score',
      labels: 'my-scale-labels',
    }
  }}
  scaleStyle="numbers"
  question="How would you rate your satisfaction with our product?"
  minLabel="Very unsatisfied"
  maxLabel="Very satisfied"
  onScoreSubmit={({ value }) => {/* ... */}}
  onFeedbackSubmit={({ value, comment }) => {/* ... */}}
/>

You can then style these classes in your app stylesheet.


See Also

  • Survey Components - See all available components and their default styles
  • Contributing - Set up local development for testing custom styles
  • Changelog - Check styling-related updates and breaking changes