Accessibility

The Frankenstein Table: CSS Grid Skin on Semantic Table Bones

A front-end experiment sets display: grid on HTML tables, keeping th/td markup while stripping native table layout — and screen readers still see a table.

  • AuthorJames Calloway
  • ChannelAccessibility
  • Filed
  • Read3 min
The Frankenstein Table
The Frankenstein TableAI-generated
  • The technique sets display: grid on a <table> while keeping th/td markup intact
  • tbody uses display: contents and rows/cells use display: block to strip native table layout
  • VoiceOver and keyboard navigation treat the hybrid as a real table
  • The grid version reuses grid-template-columns: auto auto 1fr and gap: 2lh from the div-based original
  • Table-rescue variants of this approach were historically used to make tables responsive

A table that reads like a table but lays out like a grid: that's the provocation at the heart of a new front-end experiment dubbed "The Frankenstein Table," which sets display: grid on a <table> element and reports that no browser — nor VoiceOver, nor keyboard navigation — has rejected the hybrid so far.

The author's starting point is an old disappointment. When Flexbox and CSS Grid first arrived, the author admits it was naive to expect that alignment properties such as align-self and justify-content would one day work on block and inline elements — tables, lists, fixed-position boxes. The mechanics could differ under the hood, depending on the reference boxes, but the syntax seemed like it should be universal: push to an edge, hold the center, spread items evenly. That never happened. So the experiment asks a different question: what if you build it yourself?

What does the technique actually do?

The method takes the soul of an HTML table and stitches it back together with CSS Grid. The markup keeps <table>, <tr>, <th> and <td>, so it still reads as tabular data. But the CSS overrides the table's native layout:

  • table { display: grid; } swaps the table layout for a grid container
  • tbody { display: contents; } bypasses the tbody box entirely
  • tr, tr > * { display: block; } strips the table-row and table-cell display roles

With those overrides in place, the full grid toolkit opens up — grid-template-columns, gap, source-order independence and intrinsic sizing — while the underlying markup stays tabular. The author notes that some form of this approach was used in the past to make tables responsive.

Why not just use a real table or real divs?

The author is careful to defend honest tables first. Straight-up HTML tables provide a clean semantic layout that browsers translate perfectly for assistive technology, complete with a <caption> element. On the CSS side, Grid earns its place in layouts for its intrinsic responsiveness, source-order independence and positioning. The author's prescription for most cases: use Grid for layout, and let HTML tables do the work of actually displaying tabular data.

But there's a middle ground the author calls pseudo-semantic. Technically <table> isn't a presentational element like a <div> — it's semantic, meaning the browser and the author share a common meaning for it. Yet even setting the browser aside, when a human reads <th>, they believe it's a heading followed by data. Compare:

<div class="product-title">Wall Calendar</div> versus <th>Wall Calendar</th>

How does the card example work?

The demonstration converts a bank card built from <article> and <div> elements — card number, bank name, card holder — into <table>/<tr>/<th>/<td> markup. The original CSS used:

.card {
  display: grid;
  grid-template-columns: auto auto 1fr;
  gap: 2lh;
}

The table version keeps those exact declarations and adds the three soul-stripping overrides. Elements like <h1> and <strong> carry semantics but lack the heading-to-data connection that <th> and <td> share, and <dt>/<dd> are better reserved for textual structures like glossaries.

The author's verdict: the pseudo-semantic table is easier to scan than a handful of generic divs. You keep the pseudo-semantics of the table and the layout power of CSS Grid. Browsers haven't shunned the Frankenstein creation, and VoiceOver and keyboard navigation treat it as a real table.

Should semantics survive the reanimation?

The author concedes the result looks "more than a little gross" and cuts against the grain. Web practice encourages a separation of concerns between content and presentation, and this technique achieves exactly that — without affecting the table's semantics, such as its ARIA role. The open question the piece leaves dangling: maybe it should affect those semantics. After all, there are plenty of other HTML elements that CSS is equally capable of busting open.

Original: freecodecamp.org

Share this article:

More from James Calloway

James Calloway

Show full bio

Senior reporter covering regulation, policy and their impact on Product and interaction design, design systems at Interface Wire.

63 articles

Related articles

  1. HTML `headers` Attribute Tested Across 8 Screen Reader Pairings

  2. tidy-typography.css: A Reset That Lets CSS Do the Typographer's Job

  3. CSS random() Ships in Safari and Chrome 156: A Design Guide

  4. CSS-Tricks Starts Redesign Rollout, Cutting Zipped CSS by 22%

« Previous articleNext article »