CSS Parts
Style SenseFolks surveys with ::part(). Shadow DOM blocks ordinary page selectors from reaching survey internals.
Use the part names listed in each component's reference.
Why does my page CSS not style the survey?
Shadow DOM isolates survey styles from your page.
A global button rule cannot style buttons inside a survey.
CSS Parts expose named elements for your stylesheet to target.
How do I use ::part()?
Use the component tag followed by ::part(name):
/* Target a specific part by name */
sf-fastpoll::part(button) {
background: #007bff;
color: white;
}
/* Target multiple parts with the same styles */
sf-fastpoll::part(heading),
sf-fastpoll::part(subheading) {
font-family: 'Georgia', serif;
}
/* Combine with pseudo-classes */
sf-fastpoll::part(button):hover {
background: #0056b3;
}
sf-fastpoll::part(button):focus-visible {
outline: 2px solid #007bff;
outline-offset: 2px;
}
/* Combine with pseudo-elements (limited support) */
sf-fastpoll::part(input)::placeholder {
color: #6c757d;
}Combine ::part() with :hover, :focus, or :focus-visible. Check browser support before targeting ::placeholder.
Shared Survey Parts
Use shared parts for your base theme, then add component-specific styles.
| Part Name | What It Targets |
|---|---|
survey-container | The outer wrapper. Set fonts, background colour, and padding here. |
heading | Primary headings and titles |
button | All button elements |
next-button | Next and Submit buttons specifically |
back-button | Back and Previous buttons |
input | Text input fields |
form-field | Form field containers |
form-label | Form labels |
error-message | Validation error messages |
button-container | Container wrapping navigation buttons |
Check each component reference for supported parts.
Styling Recipes
Match Your Brand Colours
Define reusable brand colours:
/* Define your brand variables */
:root {
--brand-primary: #6366f1;
--brand-primary-dark: #4f46e5;
--brand-primary-light: #eef2ff;
--brand-text: #1e293b;
--brand-border: var(--color__grey--450);
}
/* Apply to all SenseFolks components */
sf-fastpoll::part(button),
sf-pricepoint::part(button),
sf-userchoice::part(button) {
background: var(--brand-primary);
border: none;
border-radius: 8px;
color: white;
font-weight: 400;
padding: 12px 24px;
cursor: pointer;
transition: background 0.2s;
}
sf-fastpoll::part(button):hover,
sf-pricepoint::part(button):hover,
sf-userchoice::part(button):hover {
background: var(--brand-primary-dark);
}Custom Typography
Apply your font stack:
/* Custom typography system */
sf-userchoice::part(survey-container) {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
font-size: 16px;
line-height: 1.5;
color: var(--brand-text);
}
sf-userchoice::part(heading) {
font-size: 1.5rem;
font-weight: 700;
letter-spacing: -0.02em;
margin-bottom: 1rem;
}
sf-userchoice::part(choice-label) {
font-size: 1rem;
font-weight: 500;
}Dark Mode
Follow the system colour preference:
/* Dark mode with system preference detection */
@media (prefers-color-scheme: dark) {
sf-pricepoint::part(survey-container) {
background: #1a1a2e;
color: #e2e8f0;
}
sf-pricepoint::part(text-input) {
background: #16213e;
border-color: var(--color__grey--450);
color: #f1f5f9;
}
sf-pricepoint::part(button) {
background: #6366f1;
}
sf-pricepoint::part(button):hover {
background: #818cf8;
}
sf-pricepoint::part(validation-message) {
background: #7f1d1d;
color: #fecaca;
}
}
/* Manual dark mode toggle */
.dark sf-pricepoint::part(survey-container) {
background: #1a1a2e;
color: #e2e8f0;
}Accessible Focus States
Keep keyboard focus visible:
/* Accessible focus indicators */
sf-openfeedback::part(input):focus,
sf-openfeedback::part(textarea):focus {
outline: none;
border-color: var(--brand-primary);
box-shadow: 0 0 0 3px var(--brand-primary-light);
}
/* Focus-visible for keyboard users only */
sf-openfeedback::part(button):focus-visible {
outline: 2px solid var(--brand-primary);
outline-offset: 2px;
}
/* High contrast mode support */
@media (forced-colors: active) {
sf-openfeedback::part(button) {
border: 2px solid currentColor;
}
}Animations and Transitions
Respect reduced-motion preferences:
/* Smooth transitions */
sf-fastpoll::part(choice-option) {
transition:
border-color 0.2s ease,
background-color 0.2s ease,
transform 0.1s ease;
}
sf-fastpoll::part(choice-option):hover {
border-color: var(--brand-primary);
background: var(--brand-primary-light);
}
sf-fastpoll::part(choice-option):active {
transform: scale(0.98);
}
/* Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
sf-fastpoll::part(choice-option) {
transition: none;
}
}Responsive Sizing
Adjust spacing for smaller screens:
/* Mobile-first responsive styling */
sf-featurepriority::part(survey-container) {
padding: 1rem;
font-size: 14px;
}
sf-featurepriority::part(kano-option) {
padding: 12px;
margin-bottom: 8px;
}
/* Tablet and up */
@media (min-width: 768px) {
sf-featurepriority::part(survey-container) {
padding: 2rem;
font-size: 16px;
}
sf-featurepriority::part(kano-option) {
padding: 16px;
margin-bottom: 12px;
}
}
/* Desktop */
@media (min-width: 1024px) {
sf-featurepriority::part(survey-container) {
max-width: 600px;
margin: 0 auto;
}
}Full Theme Starter
Replace these variables with your brand values:
/* Complete theme example */
:root {
--sf-primary: #6366f1;
--sf-primary-hover: #4f46e5;
--sf-bg: #ffffff;
--sf-bg-secondary: #f8fafc;
--sf-text: #1e293b;
--sf-text-muted: #64748b;
--sf-border: var(--color__grey--450);
--sf-error: #ef4444;
--sf-success: #22c55e;
--sf-radius: 8px;
}
/* Container */
sf-fastpoll::part(survey-container) {
background: var(--sf-bg);
color: var(--sf-text);
font-family: system-ui, sans-serif;
border-radius: var(--sf-radius);
padding: 1.5rem;
}
/* Headings */
sf-fastpoll::part(heading) {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 1rem;
}
/* Choices */
sf-fastpoll::part(choice-option) {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem;
border: 2px solid var(--sf-border);
border-radius: var(--sf-radius);
margin-bottom: 0.5rem;
cursor: pointer;
transition: all 0.2s;
}
sf-fastpoll::part(choice-option):hover {
border-color: var(--sf-primary);
background: var(--sf-bg-secondary);
}
/* Buttons */
sf-fastpoll::part(button) {
background: var(--sf-primary);
color: white;
border: none;
border-radius: var(--sf-radius);
padding: 0.75rem 1.5rem;
font-weight: 400;
cursor: pointer;
}
sf-fastpoll::part(button):hover {
background: var(--sf-primary-hover);
}
sf-fastpoll::part(button):disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* Error states */
sf-fastpoll::part(error-message) {
color: var(--sf-error);
font-size: 0.875rem;
margin-top: 0.5rem;
}Keep the Theme Safe and Accessible
Use CSS custom properties for theming
Reuse variables such as
--brand-primaryacross components.Keep accessibility intact
Keep text and controls readable, with visible keyboard focus.
Respect user preferences
Support
prefers-color-scheme,prefers-reduced-motion, andforced-colors.Test across browsers
Test your theme in the browsers your users use.
Avoid changing structural layout
Changing
display,position, orflexcan break internal layout.Stick to exposed parts only
Use exposed parts; internal markup can change.
Browser Support
Minimum versions for ::part():
| Browser | Version | Notes |
|---|---|---|
| Chrome | 73+ | Full support |
| Firefox | 72+ | Full support |
| Safari | 13.1+ | Full support |
| Edge | 79+ | Full support |
Also check the component's browser requirements. IE11 is unsupported.