# Styling
SvSeeds components provide a flexible styling system. This document explains the two primary styling methods and their implementation details.
## Overview
### String-based Styling
Used when a string is specified for the `styling` prop, or when no value is provided. The specified class name is automatically applied to each part of the component. When no value is provided, the default component name is used.
### Object-based Styling
Used when an object of a specific type is specified for the `styling` prop. This allows you to specify classes individually for each part of the component. Use this approach when working with TailwindCSS.
## String-based Styling
In String-based Styling, the specified class name is applied in combination with each component part and variant.
### Example
**Basic Usage**
```svelte
```
Generated HTML (class attribute excerpt):
```html
```
**Conditional Styling Based on Variant**
```svelte
Hello
```
Generated HTML (class attribute excerpt):
```html
```
## Object-based Styling
In Object-based Styling, you can specify classes individually for each part of the component. For detailed object specifications, see [Object for Styling](#object-for-styling).
### Example
**Basic Usage**
```svelte
```
Generated HTML (class attribute excerpt):
```html
```
**Conditional Styling Based on Variant**
```svelte
Hello
```
Generated HTML (class attribute excerpt):
```html
```
## Part Name System
To ensure styling flexibility, all elements within components are assigned part names.
### Standard Part Names
The following part names are defined by default:
- `whole` - Overall component wrapper
- `top` - Top region
- `middle` - Middle region
- `bottom` - Bottom region
- `left` - Left area
- `main` - Main content area
- `right` - Right area
- `label` - Label part
- `aux` - Auxiliary part
- `extra` - Additional part
Since part names are defined as `string` type, custom components can also define custom part names. For the specific part names used by each component, refer to the individual component documentation.
## Variant System
Component styling adapts based on its current appearance variant.
### Standard Variants
The following variant names are defined by default:
- `neutral` - Default variant
- `active` - Active variant (such as selected state)
- `inactive` - Inactive variant (also used for invalid/error states)
Since variants are defined as `string` type, custom variants can also be used.
### Variant Behavior
Components fall into two categories: those that automatically manage their variant based on user interaction, and those that maintain a fixed variant. For detailed variant behavior of each component, refer to the individual component documentation.
#### Auto-Managing Components
Components like `Toggle` and `TextField` automatically update their variant in response to user interactions. For these components, the `variant` prop serves as an override for the default neutral variant.
#### Non-Auto-Managing Components
For these components, the `variant` prop directly sets the component's variant without any automatic changes.
## Theme-based Style Switching
Use CSS `prefers-color-scheme` to configure theme switching. For theme toggle functionality, refer to the [feature details](/docs/dark-toggle#feature-details) of the `DarkToggle` component.
## Animation & CSS Custom Properties
SvSeeds uses a shared convention for motion values and component-owned CSS custom properties. These props are set directly on the component, or on the child component that owns the motion, and CSS-expressible animation remains in caller CSS keyed off the existing part and variant classes.
`cssvar` maps a component-defined key to the CSS custom property name that component reads or writes. This lets you wire component internals to your own design tokens without changing the component's styling classes.
```svelte
```
`duration` sets time-based motion in milliseconds. Components that expose CSS-driven timing publish the reduced-motion-aware value through the canonical `--svs-duration` custom property.
```svelte
Content
```
`transition` is an escape hatch for JS-measured motion that CSS cannot express, such as auto-height or directional transitions. It accepts a `{ fn, params }` object; for example, Disclosure defaults to `slide` but can be swapped.
```svelte
Content
```
## Object for Styling
### Object Type
The object used in object-based styling is defined as the `SVSClass` type.
```svelte
```
### Advanced Class Value Specification
Property values can use clsx library-compatible values that are valid for [Svelte's class attribute](https://svelte.dev/docs/svelte/class) specification, as well as strings.
```ts
const styling = {
whole: ["whole-class", "class1", "class2"],
main: {
base: "main-class",
neutral: { foo, bar: !foo },
},
};
```
Do not confuse the two object shapes. A clsx condition object such as `{ foo, bar: !foo }` has boolean values and is one class value, used as the value of a single variant. The variant map, the object keyed by `base`, `neutral`, `active`, and so on, takes a `ClassValue` at each key; its values are never booleans.
### Fallback Variant Style
If the current variant is not found in the object, the style defined for `neutral` will be used as a fallback.
```svelte
Hello
```
Generated HTML (class attribute excerpt):
```html
```
### Shorthand Notation
You can omit the variant and specify class attribute values directly for part names:
```ts
const styling = {
whole: "whole-class",
main: "main-class",
};
```
This is interpreted as:
```ts
const styling = {
whole: {
base: "whole-class",
},
main: {
base: "main-class",
},
};
```
#### Important Note
Shorthand notation also accepts clsx condition objects directly. An object whose values are booleans, such as `{ foo, bar: !foo }`, is recognized as a class value and used as-is; no array wrapping is required:
```ts
const styling = {
whole: { foo, bar: !foo },
};
```
This is interpreted as:
```ts
const styling = {
whole: {
base: { foo, bar: !foo },
},
};
```
An object is treated as a variant map only when none of its values are booleans, for example `{ base: "base-class", active: "active-class" }`. Wrapping the object in an array still works and is an explicit way to force a plain class value:
```ts
const styling = {
whole: [{ foo, bar: !foo }],
};
```