Apex Grid Styles and Themes
The Apex grid styles itself out of the box. As of v3 there is no theme stylesheet to import and no configureTheme() call: the grid renders through a set of --ag-* CSS custom properties that resolve to self-contained defaults. A grid mounted with zero consumer CSS already looks complete; you re-skin it by overriding tokens.
Coming from v2's per-framework theme imports? See the v2 → v3 migration guide.
Rebranding with CSS variables
Every visual decision the grid makes resolves to an --ag-* custom property. Override them on apex-grid itself, or on any ancestor element: custom properties inherit across the shadow boundary, so a value set on a wrapper cascades into every internal component (rows, cells, header, toolbar, pager).
apex-grid {
--ag-brand: #7c3aed; /* selection, focus rings, checkboxes, active sort */
--ag-radius: 12px; /* outer card radius */
--ag-row-h: 40px; /* row height */
--ag-font: 'Inter', system-ui, sans-serif;
}
Overriding the ~12 brand and surface tokens is enough to re-skin the entire grid. The brand-derived washes (--ag-brand-soft, --ag-brand-line, …) are mixed from --ag-brand with color-mix(), so a one-line brand change cascades to every tint automatically.
Light/dark theming is just a matter of swapping the surface and text tokens under a class or media query:
.dark apex-grid {
--ag-surface: #0f172a;
--ag-surface-alt: #111c33;
--ag-text: #f8fafc;
--ag-text-body: #e2e8f0;
--ag-hairline: rgba(255, 255, 255, 0.12);
}
Token reference
The full token surface lives on the grid host. Defaults shown below are the self-contained fallbacks; the brand tokens additionally re-tint from an Ignite UI palette if your app happens to define one (see Ignite UI auto-tint).
Brand
| Token | Default | Purpose |
|---|---|---|
--ag-brand | #0d6fd3 | Primary blue: selection, focus, checkboxes, active sort |
--ag-brand-strong | #0a56b8 | Hover / pressed brand state |
--ag-brand-soft | brand @ 10% | Selected-row / chip wash |
--ag-brand-softer | brand @ 7% | Chip / control wash |
--ag-brand-line | brand @ 18% | Chip / search borders |
Neutral chrome & surfaces
| Token | Default | Purpose |
|---|---|---|
--ag-hairline | rgba(15,23,42,.08) | Header / structural gridlines |
--ag-row-hover | neutral wash | Row hover background (opaque) |
--ag-surface | #fff | Grid card background |
--ag-surface-alt | #f9fafb | Alternating row tint |
--ag-surface-elevated | subtle gradient | Header background |
--ag-border | rgba(15,23,42,.05) | Row separators |
Sticky regions (header, footer, pinned columns) paint background: inherit, so the surface tokens must stay opaque: a translucent surface lets scrolled content bleed through.
Text
| Token | Default | Purpose |
|---|---|---|
--ag-text | #111827 | Primary text |
--ag-text-body | #1f2937 | Row text |
--ag-text-muted | #6b7280 | Roles, labels |
--ag-text-subtle | #9ca3af | Placeholder, ellipsis |
--ag-text-on-brand | #fff | Text on brand-filled surfaces |
State
| Token | Default | Purpose |
|---|---|---|
--ag-good / --ag-good-text / --ag-good-soft | green | Positive / healthy state |
--ag-watch / --ag-watch-text / --ag-watch-soft | amber | Warning / trial state |
--ag-risk / --ag-risk-text / --ag-risk-soft | red | Negative / churn state |
--ag-gold / --ag-gold-line / --ag-gold-text | gold | Accent pill (e.g. Enterprise badge) |
--ag-shadow-card | soft floating shadow | Reusable elevated-card shadow (see below) |
Typography
| Token | Default | Purpose |
|---|---|---|
--ag-font | Inter stack | Grid font family |
--ag-fs-cell | 12px | Cell text size |
--ag-fs-cell-secondary | 10.5px | Role line / header labels |
--ag-fs-tiny | 10px | Tags, page ellipsis |
--ag-fw-regular / --ag-fw-semibold / --ag-fw-bold | 500 / 600 / 700 | Font weights |
--ag-tracking-tight / --ag-tracking-header | -0.005em / 0.05em | Letter spacing |
--ag-leading | 1.4 | Line height |
Spacing & sizing
| Token | Default | Purpose |
|---|---|---|
--ag-cell-pad-x | 10px | Horizontal cell padding |
--ag-row-h / --ag-header-h | 36px | Row / header height |
--ag-toolbar-pad / --ag-footer-pad | none | Toolbar / footer padding |
--ag-radius | 18px | Outer card radius |
--ag-radius-sm / --ag-radius-xs / --ag-radius-pill | 6px / 4px / 20px | Chips, checkboxes, badges |
Motion
| Token | Default | Purpose |
|---|---|---|
--ag-ease | cubic-bezier(.2,.8,.2,1) | Shared easing curve |
--ag-dur-fast / --ag-dur-med / --ag-dur-slow | 120ms / 180ms / 240ms | Hover, chevron, fill transitions |
Grid shadow / edge
The grid host shows a flat 1px hairline edge by default, with no floating-card shadow. The look is controlled by a dedicated override hook, --ag-grid-shadow. This is an override hook, not a default token (it is not part of the token list above):
apex-grid { --ag-grid-shadow: var(--ag-shadow-card); } /* restore the elevated card */
apex-grid { --ag-grid-shadow: none; } /* remove the edge entirely */
--ag-shadow-card is the reusable soft floating shadow defined in the token surface; assigning it to --ag-grid-shadow reproduces the elevated card look from earlier versions.
Ignite UI auto-tint
The grid does not depend on Ignite UI and never did anything with it beyond one pass-through call, which is why the dependency was removed in 3.5.0. The tinting hooks survived that removal, because they are nothing more than CSS fallbacks: --ag-brand resolves to var(--ig-primary-500, #0d6fd3) and --ag-brand-strong to var(--ig-primary-700, …).
So if your page defines --ig-primary-* (by loading any Ignite UI base theme: Bootstrap, Material, Fluent, Indigo, light or dark), the grid picks the palette up with no configuration, and a grid on a page that does not keeps the self-contained premium blue. You do not have to install anything for this, and you never did: any stylesheet that sets --ig-primary-500 will drive it.
If you are not in an Ignite UI app, set --ag-brand directly instead. That is what the Themes demo below does.
Removed in 3.5.0: the
--igx-*custom-property level. Every colour rule used to resolve through three levels and the first never fired, because--igx-*is the naming convention of a different package.--ag-*overrides and the unprefixed semantic variables behave exactly as before.
Live examples
- Custom Styling: light/dark theme built entirely from
--ag-*overrides. - Themes: four brand presets in light and dark, each built from
--ag-brandplus thetintedtheme flag, with no external CSS.