TanStack Charts inherits the surrounding application instead of installing a global visual theme. The default chart theme uses:
Set the container's color and the chart follows normal light and dark CSS:
.chart-card {
color: #172033;
background: #ffffff;
}
@media (prefers-color-scheme: dark) {
.chart-card {
color: #e6edf7;
background: #111827;
}
}Override the default categorical palette at any container boundary:
.revenue-chart {
--ts-chart-1: #2563eb;
--ts-chart-2: #f97316;
--ts-chart-3: #10b981;
--ts-chart-4: #8b5cf6;
--ts-chart-5: #ec4899;
--ts-chart-6: #06b6d4;
}This is the lowest-cost path for application branding. It also preserves automatic theme changes without rebuilding a chart definition.
Use theme when a chart needs explicit scene colors:
const definition = defineChart({
marks,
x,
y,
theme: {
foreground: '#e5e7eb',
muted: '#94a3b8',
grid: '#334155',
background: '#0f172a',
palette: ['#38bdf8', '#fb7185', '#4ade80'],
},
})theme is partial. Omitted fields retain defaults. A responsive definition's chart context receives the default build-time theme, which is useful when marks need the shared palette or foreground tokens. A theme returned by that same builder is merged afterward while the scene is created, so read an application-supplied theme from the builder's captured values when it must use those overrides.
Do not encode semantic status by reading the current theme in data preparation. Keep meaning stable and choose theme-appropriate paint at render time.
Built-in marks expose the paint styles relevant to their geometry: fill, stroke, opacity, widths, line caps, dashes, corner radius, and font properties. A style can be fixed or data-driven where the mark's option accepts a visual channel.
Keep these responsibilities separate:
For categorical or quantitative color mapping, use the canonical Legends and Color guide.
The Canvas renderer resolves scene paints such as currentColor and CSS custom properties against the chart's computed environment. It inherits the root font and repaints after relevant ancestor class, style, data-theme, color-scheme, forced-colors, or viewport changes.
Rasterized scene nodes are not DOM descendants. A node's className therefore cannot be targeted by a CSS selector after paint. Put data-dependent fill, stroke, opacity, and font choices in mark options or the chart theme; use container CSS for palette variables, inherited color, and typography.
Gradients are opt-in SVG resources. Declare them on the chart and render with the resource-aware SVG renderer:
import { renderChartSvgWithResources } from '@tanstack/charts/svg/resources'
const definition = defineChart({
marks,
x,
y,
gradients: [
{
id: 'area-fill',
x1: 0,
y1: 1,
x2: 0,
y2: 0,
stops: [
{ offset: 0, color: '#2563eb', opacity: 0.08 },
{ offset: 1, color: '#2563eb', opacity: 0.7 },
],
},
],
})Use url(#area-fill) as the mark paint and pass renderSvg: renderChartSvgWithResources to the host or adapter. idPrefix scopes resource and clip IDs when several charts share a document.
Set clip: true when marks should be clipped to the resolved plot rectangle. Clipping is a geometry policy, not a substitute for correct scale domains.
Canvas consumes the same declared gradients and group clips without the resource-aware SVG serializer. A Canvas gradient needs measurable node bounds; path-only geometry with no point bounds should use an explicit paint instead.
The native tooltip is an HTML element inside the chart container by default. Give it a class through tooltip.className and style that class in application CSS:
const tooltip = {
className: 'revenue-tooltip',
}With portal: true, the preferred manual-Popover path keeps the element under the chart in the DOM, so inheritance and scoped selectors continue to work. If Popover is unavailable or fails, the fixed fallback moves the element under the chart's ownerDocument body. Use a document-level selector for its class and put required fallback tokens on that class or a shared document ancestor.
Every framework adapter can compose native application content with the default rows. See Tooltips and Focus.