Styling Overview
XY has two rendering surfaces. Chart chrome—titles, axis labels, legends, tooltips, controls, and annotation labels—is DOM and participates in the normal CSS cascade. Data marks are painted by WebGL, SVG, or the native rasterizer, so XY compiles a deliberate CSS-property subset for them instead of claiming that arbitrary browser selectors can reach a canvas.
Customize by part
Start with the visible part you want to change. Each link opens the exact section that owns it.
- Fill, stroke, opacity, and gradients — area, line, point, bar, and column paint. Open section →
- Axes, grid, and ticks — axis lines, horizontal guides, tick marks, and tick text. Open section →
- Color scales and colorbars — continuous palettes, domains, ticks, and scale chrome. Open section →
- Legend — content, placement, swatches, and DOM styling. Open section →
- Tooltip — fields, formatting, placement, and container styling. Open section →
- Annotations — rules, bands, arrows, markers, and callouts. Open section →
- Interaction chrome — crosshair, selection, and toolbar controls. Open section →
- Themes and Export — reusable palettes, dark mode, fonts, and output behavior. Open page →
Choose the styling surface
Start with the thing you want to change. DOM chrome can use classes or arbitrary safe DOM declarations; rendered geometry must use XY's validated mark or axis vocabulary.
If you are unsure, use this shortcut:
- Styling a line, point, area, bar, or grid? Use its typed props or mark
style=. - Styling a title, legend, tooltip, control, tick label, or annotation label? Use a slot class/style or the component's local class/style.
- Styling the chart as a whole or defining reusable colors? Use chart
class_name/styleorxy.theme(). - Styling only a self-contained HTML or Chromium export? Use
custom_css.
What “your styles win” means
XY's built-in visual chrome rules live in the low-priority base cascade
layer and use :where(...), which has zero CSS specificity. A later utility
layer or ordinary unlayered author selector therefore overrides the default
background, color, padding, border, font, shadow, or cursor without
!important.
The promise is scoped to built-in visual defaults. XY still applies structural
inline layout—position, size, z-index, and interaction state—and an explicit
inline styles[slot] or per-annotation style naturally outranks a class. Marks
follow their compiled style contract rather than the DOM cascade.
Styling troubleshooting
Start by identifying whether the thing you want to change is DOM chrome or a
rendered mark. Inspect titles, legends, tooltips, controls, ticks, and labels as
ordinary elements with data-xy-slot; style lines, areas, points, bars, and
other canvas geometry through typed props or mark style=.
For build, export, and adapter failures beyond styling, continue with the Troubleshooting guide.
The five styling destinations
- Styling Overview (you are here) — identify the rendering surface and choose the right styling mechanism.
- Examples — start from a polished, copyable chart or experiment with the interactive palette playground. Open Examples →
- Customize Each Part — change marks, axes, grid, color scales, legends, tooltips, annotations, and interaction chrome. Open Customize Each Part →
- Themes and Export — define reusable tokens, dark mode, fonts, and consistent HTML, SVG, or PNG output. Open Themes and Export →
- Advanced Styling Gallery — inspect specialized renderer paths, uncertainty, density, facets, and export edge cases. Open Advanced Styling Gallery →