CSS Classes Reference

Complete reference for all Clarflow CSS classes. Target and style every part of your funnel — questions, inputs, buttons, headers, and more.

Clarflow CSS Classes Reference

Target and style every part of your funnel with custom CSS. All classes follow the cf- prefix convention and are organized in three tiers: global, step-level, and instance-level.


Layout & DOM Structure

The funnel renders as a 3-child flex column that fills the viewport:

[data-clarflow-root]               <- flex-col, 100dvh, overflow:hidden  (also .cf-root)
  |- [data-clarflow-header]         <- flex-shrink:0 (logo, back, progress)
  |- [data-clarflow-content]        <- flex:1, overflow-y:auto (ONLY scrollable area)  (also .cf-content)
  |    └─ .cf-step                  <- step container
  |         └─ .cf-step-content     <- padded inner box (default content padding)
  └─ [data-clarflow-button-portal]  <- flex-shrink:0 (continue button)  (also .cf-button-portal)

Protected properties (cannot be overridden by custom CSS):

  • [data-clarflow-root]: display, flex-direction, height, overflow
  • [data-clarflow-content]: flex, min-height, overflow-y
  • [data-clarflow-button-portal]: flex-shrink

Always use !important when overriding inline styles. CSS is auto-scoped inside [data-clarflow-root].


Step Classes

ClassDescription
.cf-stepEvery step container
.cf-step-contentPadded inner box inside each step (carries the default content padding)
.cf-step-{N}Specific step by position (1-based)
.cf-step-firstFirst step in the funnel
.cf-step-lastLast step in the funnel
.cf-step-oddSteps in odd positions (1, 3, 5…)
.cf-step-evenSteps in even positions (2, 4, 6…)

.cf-step-content is the child of .cf-step that holds the step's elements with the default padding. Zero its padding to go full-bleed / edge-to-edge (covers, hero images, custom HTML).

Examples:

/* Style only the first step */
.cf-step-first {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
}

/* Add extra padding to the last step */
.cf-step-last {
  padding-bottom: 60px !important;
}

/* Full-bleed step: kill the inner padding so a cover/hero hits the edges */
.cf-step-3 .cf-step-content {
  padding: 0 !important;
}

Content padding variables

.cf-step-content's padding is driven by two CSS variables (so you can adjust it without a structural selector). Set them on a step (or globally) and they cascade into the inner box:

VariableDefaultControls
--cf-content-padding-x24pxLeft/right padding of .cf-step-content
--cf-content-padding-y32pxTop/bottom padding of .cf-step-content
/* Full-bleed cover on step 1 — zero the vertical padding via the variable */
.cf-step-1 { --cf-content-padding-y: 0; }

/* Tighter horizontal gutters across the whole funnel */
.cf-step { --cf-content-padding-x: 12px; }

Step Transition Animations

Add an animation when the funnel moves between steps. There's one catch: the renderer reuses the same .cf-step DOM node and only swaps the step class, so an animation keyed on .cf-step alone fires once on load and never re-fires. The standard fix is to key the animation off the parity classes .cf-step-odd / .cf-step-even — they flip on every navigation, which restarts the animation each step.

Define two identical but differently named keyframes (one per parity) and point each parity class at one:

@keyframes cf-slide-a {
  from { opacity: 0; transform: translateX(24px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes cf-slide-b {
  from { opacity: 0; transform: translateX(24px); }
  to   { opacity: 1; transform: translateX(0); }
}

.cf-step {
  animation-duration: 0.3s !important;
  animation-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1) !important;
  animation-fill-mode: both !important;
}

.cf-step-odd  { animation-name: cf-slide-a !important; }
.cf-step-even { animation-name: cf-slide-b !important; }

Why two keyframes? A CSS animation only restarts when its animation-name actually changes. cf-slide-a and cf-slide-b are identical but differently named, so alternating them per parity forces the browser to re-run the animation on every step.

Swap the transform for any effect: slide up (translateY(24px)), pop (scale(0.96)), or a pure fade (drop the transform and animate opacity only).


Element Type Classes

Every sub-element gets a global class based on its type:

ClassElement
.cf-titleTitle elements
.cf-textText blocks
.cf-imageImage elements
.cf-questionQuestion elements
.cf-inputInput fields
.cf-dropdownDropdown selects
.cf-loadingLoading elements
.cf-custom-htmlCustom HTML blocks

Step-scoped: .cf-step-{N}-{type} (e.g., .cf-step-2-question)

Instance-scoped: .cf-step-{N}-el-{E} (e.g., .cf-step-2-el-1 for the first element in step 2)

Inner element hooks — target the rendered content directly (no Tailwind/structural selectors needed):

ClassElement
.cf-title-textThe title's text element (h1 / rich-text body)
.cf-text-bodyThe text block's paragraph / rich-text body
.cf-input-fieldThe <input> element itself
.cf-dropdown-selectThe <select> element itself
.cf-custom-html-frameThe custom-HTML <iframe>

Question Type & Layout Classes

ClassDescription
.cf-question-singleSingle-select question
.cf-question-multiMulti-select question
.cf-question-layout-listList layout
.cf-question-layout-gridGrid layout (2 columns)
.cf-optionsThe options container (wraps all option buttons)
.cf-options-listOptions container in list layout
.cf-options-gridOptions container in grid layout

Examples:

/* Make single-select options larger */
.cf-question-single .cf-option {
  padding: 16px 20px !important;
  font-size: 18px !important;
}

/* Add a border to grid layout questions */
.cf-question-layout-grid {
  border: 2px dashed #e5e7eb !important;
  border-radius: 12px !important;
  padding: 16px !important;
}

Input Type Classes

ClassInput Type
.cf-input-textText input
.cf-input-emailEmail input
.cf-input-numberNumber input
.cf-input-telPhone input
.cf-input-urlURL input
.cf-input-passwordPassword input

Examples:

/* Style email inputs differently */
.cf-input-email .cf-input-field {
  border-color: #3b82f6 !important;
}

/* Add phone icon styling */
.cf-input-tel .cf-input-field {
  padding-left: 40px !important;
}

Loading Style Classes

Every loader is wrapped in .cf-loading plus a style variant. Each style exposes hooks for its inner parts.

ClassStyle variant
.cf-loading-barBar-style progress loader
.cf-loading-circleCircle/spinner loader
.cf-loading-stepsMulti-step checklist loader

Shared (bar + circle):

ClassElement
.cf-loading-textLoading label / status text
.cf-loading-percentThe percentage readout

Bar loader:

ClassElement
.cf-loading-bar-wrapThe bar's container
.cf-loading-bar-trackThe track (background)
.cf-loading-bar-fillThe animated fill

Circle loader:

ClassElement
.cf-loading-circle-graphicThe circle container
.cf-loading-circle-svgThe SVG element
.cf-loading-circle-trackThe background ring
.cf-loading-circle-fillThe animated progress ring

Steps loader — a checklist of rows, each moving pendingloadingcompleted:

ClassElement
.cf-loading-steps-wrapThe steps loader container
.cf-loading-steps-listThe list of step rows
.cf-loading-stepA single step row
.cf-loading-step-pendingStep row in the pending state
.cf-loading-step-loadingStep row in the loading state
.cf-loading-step-completedStep row in the completed state
.cf-loading-step-labelThe step's text label
.cf-loading-step-percentThe step's percentage (loading state)
.cf-loading-step-trackThe step's bar track (loading state)
.cf-loading-step-fillThe step's bar fill (loading state)
.cf-loading-step-dotThe bullet dot (pending state)
.cf-loading-step-checkThe check badge (completed state)
.cf-loading-step-dividerThe divider line (completed state)

Steps loader modal — an optional prompt shown during a step:

ClassElement
.cf-loading-modal-overlayThe dimmed backdrop
.cf-loading-modalThe modal card
.cf-loading-modal-warningThe warning line
.cf-loading-modal-questionThe question text
.cf-loading-modal-actionsThe button row
.cf-loading-modal-confirmThe confirm (yes) button
.cf-loading-modal-dismissThe dismiss (no) button

Option Classes

ClassDescription
.cf-optionEvery option button
.cf-option-selectedCurrently selected option
.cf-option-has-emojiOption that contains an emoji
.cf-option-has-imageOption that contains an image
.cf-option-has-subtextOption that contains subtext
.cf-option-contentThe option's content row. In grid layout this is the footer band below the image — colour/pad it to style the label band
.cf-option-labelThe option's main label text. If the label was formatted in the editor it contains inline elements (strong, em, span…) whose inline styles beat rules set on this class — target .cf-option-label strong etc., or use !important, to override them
.cf-option-subtextThe option's subtext line
.cf-option-emojiThe option's emoji
.cf-option-mediaThe image wrapper in grid layout (size / aspect-ratio / crop the image here)
.cf-option-imageThe <img> element itself (in grid layout it sits inside .cf-option-media)
.cf-option-indicatorThe radio/checkbox indicator
.cf-option-indicator-radioSingle-select (radio) indicator — the outer circle
.cf-option-indicator-checkboxMulti-select (checkbox) indicator
.cf-option-indicator-dotThe small inner dot of a selected radio
.cf-option-indicator-checkCheckmark inside a selected checkbox

Recolouring a selected radio: when a radio is selected, the outer circle (.cf-option-indicator-radio) is filled with --cf-primary and the inner dot (.cf-option-indicator-dot) is filled with --cf-background (so the dot shows as a hole). Setting background on .cf-option-indicator-dot alone makes the dot the same colour as the already-filled circle, so the whole control reads as a solid disc. To change the colours, style the circle and the dot separately — e.g. .cf-option-indicator-radio { background: #111 !important } and .cf-option-indicator-dot { background: #fff !important }.

Step-scoped: .cf-step-{N}-option

Instance-scoped: .cf-step-{N}-el-{E}-option-{O} (e.g., .cf-step-1-el-1-option-3)

Examples:

/* Highlight options with images */
.cf-option-has-image {
  border: 2px solid #10b981 !important;
}

/* Style selected state */
.cf-option-selected {
  transform: scale(1.02) !important;
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3) !important;
}

/* Grid cards: square the image and colour the footer label band */
.cf-question-layout-grid .cf-option-media {
  width: 100% !important;
  aspect-ratio: 1 / 1 !important;
  overflow: hidden !important;
}
.cf-question-layout-grid .cf-option-content {
  background: var(--cf-option-bg) !important;
  padding: 12px !important;
}
.cf-question-layout-grid .cf-option-selected .cf-option-content {
  background: var(--cf-primary) !important;
}

Image Classes

ClassDescription
.cf-image-singleSingle image display
.cf-image-carouselImage carousel (2+ images)

Field State Classes

ClassElementDescription
.cf-requiredInput/Dropdown wrapperField is required
.cf-labelLabel elementInput or dropdown label
.cf-input-errorError paragraphInput validation error message
.cf-dropdown-errorError paragraphDropdown validation error message

Examples:

/* Style required field labels */
.cf-required .cf-label {
  font-weight: 700 !important;
}

/* Custom error message styling */
.cf-input-error {
  color: #dc2626 !important;
  font-style: italic !important;
}

ClassDescription
.cf-dropdownDropdown wrapper
.cf-dropdown-selectThe <select> element itself
.cf-dropdown-optionEvery dropdown option
.cf-dropdown-errorDropdown validation error

Step-scoped: .cf-step-{N}-dropdown-option

Instance-scoped: .cf-step-{N}-el-{E}-dropdown-option-{O}


Header & Button Classes

ClassElementDescription
.cf-rootRoot containerFunnel root (class alias of [data-clarflow-root])
.cf-contentContent areaScrollable content (class alias of [data-clarflow-content])
.cf-headerHeader containerThe top header bar
.cf-header-rowHeader inner rowThe flex row holding back + logo + step counter (adjust its padding/alignment)
.cf-header-backBack button wrapperBack navigation area
.cf-header-logoLogo wrapperBrand logo area
.cf-header-stepStep counter wrapperThe "X of Y" counter area
.cf-header-step-countStep counter textThe "X of Y" text element
.cf-header-progressProgress wrapperProgress bar area
.cf-header-progress-trackProgress trackThe progress bar background
.cf-header-progress-fillProgress fillThe progress bar filled portion
.cf-header-dividerHeader dividerBorder line below the header / progress bar
.cf-buttonButton containerContinue button wrapper (includes padding/shadow)
.cf-button-textButton elementThe actual continue button
.cf-button-portalPortal divButton portal target at bottom of viewport

Examples:

/* Custom header background */
.cf-header {
  background: #1a1a2e !important;
  border-bottom: 2px solid #16213e !important;
}

/* Round the continue button */
.cf-button-text {
  border-radius: 50px !important;
  text-transform: uppercase !important;
  letter-spacing: 1px !important;
}

/* Hide the progress bar */
.cf-header-progress {
  display: none !important;
}

Instance Targeting

For precise control, combine step number with element index:

PatternExampleTargets
.cf-step-{N}-el-{E}.cf-step-2-el-1First element in step 2
.cf-step-{N}-el-{E}-option-{O}.cf-step-1-el-1-option-3Third option of first element in step 1
.cf-step-{N}-el-{E}-dropdown-option-{O}.cf-step-3-el-2-dropdown-option-1First dropdown option of second element in step 3

All indices are 1-based (start from 1, not 0).


Real-World Examples

Dark theme override

.cf-step {
  background: #0f172a !important;
  color: #e2e8f0 !important;
}

.cf-option {
  background: #1e293b !important;
  border-color: #334155 !important;
  color: #e2e8f0 !important;
}

.cf-option-selected {
  border-color: #3b82f6 !important;
  background: #1e3a5f !important;
}

.cf-button-text {
  background: #3b82f6 !important;
  color: white !important;
}

Style only email inputs on step 3

.cf-step-3 .cf-input-email .cf-input-field {
  border: 2px solid #10b981 !important;
  border-radius: 8px !important;
  padding: 12px 16px !important;
}

.cf-step-3 .cf-input-email .cf-label {
  color: #10b981 !important;
  font-size: 14px !important;
}

Highlight multi-select questions

.cf-question-multi {
  background: #fefce8 !important;
  border: 1px solid #fbbf24 !important;
  border-radius: 12px !important;
  padding: 16px !important;
}

.cf-question-multi .cf-option {
  border-color: #f59e0b !important;
}

Custom progress bar

.cf-header-progress-track {
  height: 6px !important;
  border-radius: 3px !important;
}

.cf-header-progress-fill {
  background: linear-gradient(90deg, #3b82f6, #8b5cf6) !important;
}

Stop Losing 98% of Your Traffic

Join hundreds of DTC brands using Clarflow to turn browsers into buyers with AI-powered product quizzes.

Contact Sales
Free forever plan
30-day money-back guarantee
Cancel anytime