Styling System

Style with full control.

Learn how to style Svelte Atoms components using Tailwind CSS, variants, presets, and custom CSS.

Overview

Tailwind utilities, a variant system, global presets, and cn() — all composable, all optional.

Every component accepts a class prop that supports strings, arrays, and objects. The styling system builds on Tailwind CSS utilities, enhanced by the cn() utility for intelligent merging, and integrated with the preset system for global theming.

String

class="bg-primary text-white px-4"

Simple static classes

Array

class={['base', isActive && 'active']}

Mix static and conditional

Object

class={{ active: isActive, hidden: !show }}

Boolean-keyed map

Mixed

class={['base', condition && 'cls', klass]}

Combine all forms

Works with Tailwind, CSS modules, or any styling solution

cn() utility for intelligent class merging

Color tokens via CSS variables

Conditional class application

Variant system with compounds

Reactive variants based on component state

$preset placeholder for fine-grained control

Full TypeScript support

Tailwind CSS utilities

Use Tailwind utility classes for 90% of your styling needs with full responsive support.

All component props and the class array accept any Tailwind utility. Responsive prefixes, state variants, and opacity modifiers work exactly as expected.

The cn() utility

Intelligent class merging — combines clsx for conditionals with tailwind-merge for conflict resolution.

When two conflicting Tailwind utilities are provided, the last one wins. cn() handles arrays, strings, objects, and falsy values transparently.

CSS custom properties

Semantic color tokens follow shadcn/ui conventions for maximum compatibility and theme-awareness.

Use token-based utilities like bg-primary instead of specific colors. Tokens adapt automatically to dark mode and custom themes.

background Main background color
foreground Main text color
primary Primary brand color
primary-foreground Text on primary background
secondary Secondary accent color
secondary-foreground Text on secondary background
muted Muted backgrounds
muted-foreground Muted text color
accent Accent color for highlights
accent-foreground Text on accent background
destructive Error/danger color
destructive-foreground Text on destructive background
border Border colors
input Input border color
ring Focus ring color
card Card background
card-foreground Card text color
popover Popover background
popover-foreground Popover text

Conditional styling

Apply classes based on component state using arrays, ternaries, and logical expressions.

Falsy values (false, null, undefined) are silently dropped. Arrays can be arbitrarily nested.

Variant system

Define reusable, type-safe component variants with full TypeScript inference and bond state access.

Local vs global variants

Local variants — defined with defineVariants() in the component file. Best for component-specific styling. Global variants — defined in the Preset System via setPreset(). Apply consistently across your entire app.

defineVariants() creates a type-safe variant configuration for use at the component level. Variants support multiple dimensions (size, variant, state), defaults, compound rules, and any HTML attribute — not just class.

Base Classes

Shared styling that applies to every variant

Multiple Dimensions

Combine variant, size, state independently

Default Values

Sensible fallbacks for all variant dimensions

Type Safety

Automatic TypeScript inference for variant options

Compound Variants

Extra classes when multiple conditions match

Attribute Support

Return aria-*, data-*, and any HTML attribute

Compound variants

Apply additional classes and attributes only when a specific combination of variants is active.

Compound variants fire when all listed variant keys match simultaneously. They can set classes, ARIA attributes, role, or any other HTML attribute — useful for accessibility patterns that depend on combined state.

Reactive variants

Access component bond state for variants that update automatically when internal state changes.

Pass a function to defineVariants() to receive the bond. This lets variant classes react to state like isOpen, isActive, or isDisabled without extra prop wiring.

The $preset placeholder

Control exactly where preset classes are inserted relative to your component's own classes.

Place the string '$preset' anywhere in a class array and it is replaced by resolved preset classes. Without it, preset classes are prepended automatically, which means your component defaults come after the preset baseline.

Inline styles

Reserve inline styles for dynamic values that cannot be expressed as Tailwind classes.

Use for dynamic values

  • + Dynamic dimensions (width, height) driven by state
  • + Transform values for animation (translate, rotate, scale)
  • + CSS custom property values computed at runtime

Avoid for static values

  • Static colors, padding, margins — use Tailwind
  • Fixed dimensions or spacing — use Tailwind
  • State-based classes — use conditional arrays

Best practices

Guidelines for maintainable, consistent styling across your application.

01

Prefer Tailwind utilities

Use Tailwind classes for 90% of styling — optimized, tree-shaken in production, consistent design tokens.

02

User classes override last

Place the user-provided class prop last in your array so it can always override component defaults and preset styles.

03

Use presets for repeating patterns

Define component defaults once in a preset rather than copying classes across the codebase.

04

Merge with cn()

Always use cn() when combining class values. It handles Tailwind conflicts and conditionals in one call.

05

Reserve inline styles for dynamic values

Inline style is for values that change at runtime (widths, transforms, opacity). Static styling belongs in Tailwind classes.

06

Keep specificity low

Avoid !important and overly specific selectors. Let cascade and class order handle overrides naturally.

07

Use semantic color tokens

Prefer bg-primary over bg-blue-500. Semantic tokens adapt to theme changes and dark mode automatically.

08

Extract reusable variants

When the same variant pattern repeats across components, extract it into a defineVariants() definition.

© 2026 Svelte Atoms. Open source under the MIT license.

Built with Svelte 5 · Runes · TailwindCSS