# Accessibility and SSR

> Accessibility and SSR: anatomy, keyboard behavior, state, and theming in Askr.

Source: [https://askrjs.com/docs/charts/accessibility-and-ssr](https://askrjs.com/docs/charts/accessibility-and-ssr)

Status: stable. Packages: @askrjs/askr.

**Published packages are authoritative.** Examples may lag behind a published contract. When guidance differs, verify the exports and TypeScript declarations in your installed package, then file an issue.

## Example

```tsx
import { createPlot } from '@askrjs/charts';

const Plot = createPlot<ProjectRow>();

<Plot.Root
  data={rows}
  rowKey="id"
  label="Daily revenue"
  title="Revenue"
  description="Actual revenue for the current week."
  summary={({ visibleRowCount }) => visibleRowCount + ' days shown'}
  width={720}
>
  <Plot.Line x="createdAt" y="revenue" />
</Plot.Root>
```

## Accessible summary

`Root.summary` accepts either a fixed string or a callback that receives `{ rows, sourceRowCount, transformedRowCount, omittedRowCount, visibleRowCount }`, so the accessible description can stay truthful about how many rows were actually rendered versus omitted. Pairing a summary callback with `diagnostics` is the recommended way to surface data-quality issues (invalid dates, non-finite numbers) to both developers and assistive technology.

## Heading structure

`Root`'s `title` renders a visible semantic heading, and `headingLevel` (1 through 6) lets it slot correctly into the surrounding page outline instead of always defaulting to one level. `description` supplies supporting text alongside the heading for additional context beyond the title alone.

## SSR output

Server rendering emits the reserved region, title, description, legend, summary, empty state, and keyboard/data instructions — but no graphical marks, since Canvas 2D has nothing to paint before hydration. After hydration, the root mounts three separate canvases, not one: a chrome canvas (axes, grid, static decoration), a marks canvas (the actual data drawing), and an overlay canvas for transient interaction (crosshair, brush, hover) — kept apart so redrawing a hover state doesn't force repainting the whole scene. A "View data" control materializes the full transformed table on demand rather than duplicating every row into the initial document.

## Motion and color

Without JavaScript, users still get the semantic label, summary, legend, and instructions, just not the graphical marks or the on-demand table — so no essential information should live only in a tooltip or a canvas pixel. The renderer respects reduced-motion preferences by disabling nonessential transitions while still reflecting real state changes, and series color comes from theme tokens (`--ak-chart-series-1` through `--ak-chart-series-10`) rather than hardcoded values, so contrast follows whatever theme is active.

## Documentation navigation

[Previous](https://askrjs.com/docs/charts/recipes/index.md) | [Next](https://askrjs.com/docs/charts/migration-0-1/index.md)
