Skip to content

Theming

Seizen Table uses CSS Custom Properties (CSS Variables) as its theming foundation rather than JavaScript-based styling solutions. This choice is intentional:

Zero runtime overhead — CSS variables are resolved by the browser’s CSS engine, not JavaScript. Theme changes happen instantly without React re-renders or style recalculations in JS-land.

Framework agnostic — While Seizen is a React library, CSS variables work anywhere. You can control themes from vanilla CSS, Tailwind, CSS-in-JS, or even server-rendered stylesheets. No vendor lock-in.

Inheritance by default — CSS variables cascade naturally. Set variables on :root for global theming, or scope them to a container for localized themes. Multiple SeizenTables with different themes on the same page? Just wrap each in a div with different variable values.

DevTools friendly — Inspect any element and see exactly which variables affect it. Tweak values in real-time without rebuilding. Debug theming issues visually, not through console logs.

Composable with design systems — If your app already has CSS variables for colors, spacing, or typography, you can wire them directly to Seizen’s variables. One source of truth, zero duplication.

Seizen Table provides two independent theming systems:

  1. Color Themes - Control the visual appearance (light, dark, nord)
  2. Spacing Themes - Control the density and spacing (compact, comfortable)

These can be combined to create your desired look and feel.

Customize the appearance by defining CSS variables. All variables have sensible defaults.

:root {
/* Colors */
--szui-color-text: #1f2937;
--szui-color-bg: #ffffff;
--szui-header-bg: #f9fafb;
--szui-header-color: #6b7280;
--szui-border-color: #e5e7eb;
--szui-row-hover-bg: #f3f4f6;
--szui-row-selected-bg: #eff6ff;
/* Typography */
--szui-font-family: system-ui, -apple-system, sans-serif;
--szui-font-size: 14px;
--szui-line-height: 1.5;
--szui-header-font-size: 12px;
--szui-header-font-weight: 600;
/* Border */
--szui-border-width: 1px;
--szui-border-radius: 8px;
}
:root {
/* Spacing */
--szui-cell-padding-x: 12px;
--szui-cell-padding-y: 10px;
--szui-table-gap: 0;
}

The default light theme with high contrast and clean appearance.

:root {
--szui-color-text: #1f2937;
--szui-color-bg: #ffffff;
--szui-header-bg: #f9fafb;
--szui-header-color: #6b7280;
--szui-border-color: #e5e7eb;
--szui-row-hover-bg: #f3f4f6;
--szui-row-selected-bg: #eff6ff;
}

The standard spacing theme with balanced padding.

:root {
--szui-cell-padding-x: 12px;
--szui-cell-padding-y: 10px;
--szui-table-gap: 0;
}

Use JavaScript/TypeScript to dynamically switch themes:

// Switch color theme
function setColorTheme(theme: 'light' | 'dark' | 'nord') {
const themes = {
light: {
'--szui-color-text': '#1f2937',
'--szui-color-bg': '#ffffff',
'--szui-header-bg': '#f9fafb',
'--szui-header-color': '#6b7280',
'--szui-border-color': '#e5e7eb',
'--szui-row-hover-bg': '#f3f4f6',
'--szui-row-selected-bg': '#eff6ff',
},
dark: {
'--szui-color-text': '#f9fafb',
'--szui-color-bg': '#111827',
'--szui-header-bg': '#1f2937',
'--szui-header-color': '#9ca3af',
'--szui-border-color': '#374151',
'--szui-row-hover-bg': '#1f2937',
'--szui-row-selected-bg': '#1e3a5f',
},
nord: {
'--szui-color-text': '#eceff4',
'--szui-color-bg': '#2e3440',
'--szui-header-bg': '#3b4252',
'--szui-header-color': '#88c0d0',
'--szui-border-color': '#4c566a',
'--szui-row-hover-bg': '#3b4252',
'--szui-row-selected-bg': '#434c5e',
},
};
Object.entries(themes[theme]).forEach(([key, value]) => {
document.documentElement.style.setProperty(key, value);
});
}
// Switch spacing theme
function setSpacingTheme(theme: 'compact' | 'default' | 'comfortable') {
const themes = {
compact: {
'--szui-cell-padding-x': '0.5rem',
'--szui-cell-padding-y': '0.375rem',
'--szui-table-gap': '0',
},
default: {
'--szui-cell-padding-x': '12px',
'--szui-cell-padding-y': '10px',
'--szui-table-gap': '0',
},
comfortable: {
'--szui-cell-padding-x': '1.5rem',
'--szui-cell-padding-y': '1rem',
'--szui-table-gap': '0.25rem',
},
};
Object.entries(themes[theme]).forEach(([key, value]) => {
document.documentElement.style.setProperty(key, value);
});
}