demo D112
High contrast, and why it is not just dark in htmx
Borders at 6.1:1 against 1.3:1, and drawn cell edges
WCAG 1.4.11
This grid shows a true high-contrast theme, with borders and cell edges held at a far higher contrast than a dark theme targets. It is built for readers who need strong non-text contrast, so the structure stays visible rather than just dimmed.
This is the htmx version. A server-rendered table is upgraded in place, so the page is readable before any script runs and gains the full grid when the module loads, which suits a progressively enhanced app.
The configuration
<link rel="stylesheet" href="https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.min.css">
<!-- A real, server-rendered table: readable with JavaScript off. data-field on
each header names the column that cell becomes, and data-id on each row is
the key the grid carries it under. -->
<table id="high-contrast-table" data-lattice-grid>
<thead>
<tr>
<th data-field="service">Service</th>
<th data-field="team">Team</th>
<th data-field="owner">Owner</th>
<th data-field="region">Region</th>
<th data-field="active">Active</th>
<th data-field="deprecated">Deprecated</th>
<th data-field="version">Version</th>
</tr>
</thead>
<tbody>
<tr data-id="1"><td>svc-00001</td><td>Search</td><td>k.yilmaz</td><td>Malmö</td><td>false</td><td>false</td><td>1.2.10</td></tr>
<tr data-id="2"><td>svc-00002</td><td>Mobile</td><td>m.svensson</td><td>Leeds</td><td>true</td><td>false</td><td>2.3.6</td></tr>
<tr data-id="3"><td>svc-00003</td><td>Identity</td><td>j.okafor</td><td>Zürich</td><td>true</td><td>false</td><td>1.11.1</td></tr>
<!-- the rest of the rows, rendered by your server -->
</tbody>
</table>
<script type="module">
import { hydrateTable } from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/modules/htmx.esm.min.js';
// The markup carries the rows; a server-rendered table's column types are
// declared in the config hydrateTable takes. The grid replaces the table
// where it stood.
const grid = hydrateTable(document.getElementById('high-contrast-table'), {
selection: 'multiple',
// A built-in theme tuned for maximum contrast, chosen in one line.
theme: 'high-contrast',
columns: [
{ field: 'service', title: 'Service', layout: { pin: 'start', width: 140 } },
{ field: 'team', title: 'Team', filter: { type: 'set' } },
{ field: 'owner', title: 'Owner', filter: { type: 'set' } },
{ field: 'tier', title: 'Tier', cell: { decoration: 'pill', variant: { map: { gold: 'warning', silver: 'neutral', bronze: 'info' } } } },
{ field: 'state', title: 'State', cell: { decoration: 'dot', variant: { map: { healthy: 'success', degraded: 'warning', failing: 'danger', unknown: 'neutral' } } } },
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ field: 'active', title: 'Active', type: 'boolean' },
{ field: 'deprecated', title: 'Deprecated', type: 'boolean' },
{ field: 'version', title: 'Version', layout: { width: 100 } },
],
});
</script>
Meeting WCAG contrast with a dedicated high-contrast theme
A high-contrast theme is not the dark theme with the brightness turned up. It is a separate token set built against WCAG 1.4.11’s non-text contrast requirement, so borders, focus rings and cell edges hold a ratio a dark theme never targets. Lattice Grid’s dark theme draws its row and column dividers at roughly 1.3:1 against the background, enough to read as structure when a viewer has full colour vision and normal contrast sensitivity, but well short of what a low-vision user needs to find a cell boundary. Set theme: 'high-contrast' and the same dividers move to 6.1:1, with every cell edge drawn explicitly rather than implied by alternating row colour, because relying on zebra-striping to signal a boundary fails the moment the striping itself sits below threshold. A developer reaches for this theme when building for a procurement requirement that names WCAG 2.1 AA, or for a user base that has already told you the default theme is not enough: trading floors, control rooms, and public-sector dashboards are the common cases. The theme swaps CSS custom properties rather than adding a stylesheet, so switching at runtime costs a token update and repaint, not a rebuild of the grid’s DOM, and it composes with density and reduced-motion settings already in place on the page.
Does Lattice Grid meet WCAG contrast requirements out of the box?
The default light and dark themes are tuned for readability but do not target the WCAG 1.4.11 non-text contrast minimum on structural elements such as cell borders. The high-contrast theme does: borders and focus indicators are drawn at 6.1:1 rather than the roughly 1.3:1 of the dark theme, with cell edges drawn rather than implied, satisfying the requirement without a custom stylesheet.