Styling
Three approaches, pick what fits:
- Plain CSS / Tailwind / your stylesheet of choice — works without anything special. Just import
.css. - Inline
styleattribute — pass a CSSProperties object directly to elements. flexium/css— atomic CSS-in-JS with build-time extraction.
Inline style
<div style={{ color: 'red', padding: '12px', fontWeight: 600 }}>
styled
</div>For dynamic styles based on signals:
const [active, setActive] = use(false)
<div style={{ background: active ? '#3b82f6' : '#e5e7eb' }}>...</div>Pros: zero setup. Cons: not cacheable, slightly more bytes per node.
Plain CSS / Tailwind
Import a CSS file at the entry point:
// src/main.tsx
import './global.css'
import './tailwind.css'Use class (lowercase, matching HTML) on elements:
<div class="text-red-500 font-bold">styled</div>(Note: class, not className — Flexium passes attributes straight to the DOM.)
This is the path most apps take. Tailwind v4 works out of the box.
flexium/css — atomic CSS-in-JS
For colocated styles that get extracted at build time:
import { css } from 'flexium/css'
const button = css({
padding: '8px 16px',
background: '#3b82f6',
color: 'white',
borderRadius: '8px',
cursor: 'pointer',
'&:hover': {
background: '#2563eb'
}
})
function Submit() {
return <button class={button}>Submit</button>
}At build time, vite-plugin-flexium with optimize: 'auto' extracts the rule to a static CSS file with a hashed class name (flx-abc123). Result:
- Zero runtime CSS-in-JS overhead in production
- Atomic deduplication across all
css()calls - Same class hash for identical rule sets
Pseudo-selectors and media queries
const card = css({
padding: '16px',
background: 'white',
'&:hover': { background: '#f3f4f6' },
'&:focus-visible': { outline: '2px solid #3b82f6' },
'@media (max-width: 640px)': {
padding: '8px'
}
})Theming
For app-wide design tokens, use CSS variables — works with any of the three approaches:
/* global.css */
:root {
--color-primary: #3b82f6;
--space-2: 8px;
--space-4: 16px;
}
[data-theme='dark'] {
--color-primary: #60a5fa;
}<div style={{ color: 'var(--color-primary)', padding: 'var(--space-4)' }}>...</div>Swap themes via a shared signal:
const [theme, setTheme] = use<'light' | 'dark'>('light', { key: 'theme' })
unsafeEffect(() => {
document.documentElement.dataset.theme = theme
})Composition
Compose multiple class names with a template literal or a helper:
<div class={`${base} ${active && activeStyle}`}>...</div>Or use clsx / classnames if you prefer.
Next
→ Server-Side Rendering — renderToString, hydration.