![Una Kravets](https://web.dev/images/authors/unakravets.jpg) Una Kravets [X](https://twitter.com/una) [Mastodon](https://front-end.social/@una) [Homepage](https://una.im) ![Aleks Totic](https://web.dev/images/authors/atotic.jpg) Aleks Totic [X](https://twitter.com/atotic)

<br />

TablesNG launches in Chromium 91, and fixes a [ton of bugs](https://bugs.chromium.org/p/chromium/issues/list?q=label:Target-TablesNG&can=2)
that have been a part of the web platform for years. These updates will improve
browser compatibility as a part of the
[#Compat2021](https://web.dev/blog/compat2021) effort, and improve using tables on
the web platform overall. Some of the most-starred issues include [`position:
sticky` in rows](https://bugs.chromium.org/p/chromium/issues/detail?id=702927&q=label:Target-TablesNG&can=2&sort=pri),
[subpixel geometry](https://bugs.chromium.org/p/chromium/issues/detail?id=377847&q=label:Target-TablesNG&can=2&sort=pri),
and proper
[border-collapsing](https://bugs.chromium.org/p/chromium/issues/detail?id=2902&q=label:Target-TablesNG&can=2&sort=pri).

## The TablesNG effort

TablesNG is a multi-year effort, led by Chrome developer Aleks Totic, to
completely re-architect how tables are rendered on the web. Tables are a
particular area of friction in web development, in part because of their
history.

![Parts of a table](https://developer.chrome.com/static/blog/tablesng/image/parts-a-table-f79a57ce719c.png)

Tables were added to HTML in 1994, then used as the [primary method](https://codeburst.io/a-brief-history-of-trends-in-web-design-845b6acb35bc)
to create complex page layouts for many years. They are still found all over the web,
although modern usage is generally to display tabular data.
However, there are big differences in table behavior across browsers,
many of which came about due to the tables specification being incomplete and lacking detail.
Tables were also implemented in browsers before many CSS features:
orthogonal writing modes, `position:relative`, `box-sizing`, flexbox containers,
and more. So support for many of these features was inconsistent.
![Space Jam website screenshot](https://developer.chrome.com/static/blog/tablesng/image/space-jam-website-screens-01a655505a646.png) The innovative table layout that comprised the Space Jam website, via [Shannon Draper](https://codeburst.io/a-brief-history-of-trends-in-web-design-845b6acb35bc).

The new spec, CSS Table Module Level 3, was written after Edge
reimplemented tables in 2018. TablesNG is a re-architecture effort that
aims to not only follow this new specification, but to also fix a lot of the
inconsistencies in tables along the way. Some of the most visible changes that
have come out of this are:

- Enabling sticky positioning in rows for long tables that scroll.
- Fixing alignment with sub-pixel geometry and table borders.
- Improved painting for backgrounds and borders.

## `position: sticky` in rows

One of the biggest asks and most frustrating things about styling tables in the
past was the lack of support for `position: sticky` in rows. This feature would enable
a table header to remain on the page as you scroll, and give context to long
data tables. By the time you scroll the header out of view and you're looking at
a table full of numbers, it's easy to forget what those numbers mean.
The table header is not remaining in the sticky position, despite `position: sticky` being applied to the `<thead>`.

The reason we've had this bug around for so long is because `position: sticky`
was specified well after HTML tables came out. Before this fix, headers with an
intended `position: sticky` were just [converted into](https://github.com/w3c/csswg-drafts/issues/3136) `position: static`, but
now, you can use `position: sticky` anywhere in the tables: on headers (`<thead>`) or
vertical axis labels.
Table header has sticky positioning in Chromium 91+. [See Demo on
Codepen](https://codepen.io/una/pen/zYZdgMJ).

> [!WARNING]
> **Warning:** If you're using `position: sticky` on a table, make sure it doesn't have borders. Border painting is currently an open cross-browser compatibility issue, as borders belong to the table, not the header row itself.

## Improved border painting and background painting

One of the oldest table
[bugs](https://bugs.chromium.org/p/chromium/issues/detail?id=2902) dates
back to September 2008. It was filed almost as soon as Chrome was released, and was
never able to be fixed due to the old table architecture. The issue surrounds
table painting and collapsed borders.

The way that tables are painted, in order of `z-index`, is: cells \> rows \>
sections \> tables. They then are painted by the order they appear in the DOM
(Document Object Model), though the cells themselves are in reverse DOM order,
where the first cell in the table is the top-most.

![z-index order of tables](https://developer.chrome.com/static/blog/tablesng/image/z-index-order-tables-581ca04d685cf.png)

So the issue here is that borders belong to the table, not the cell, in the old
way that tables were painted. Collapsed borders are painted when table paints its foreground.
This means that a single table cell could not have
multiple borders:
![correct and incorrect table rendering](https://developer.chrome.com/static/blog/tablesng/image/correct-incorrect-table-529497538966.png) Left: Incorrect table rendering prior to TablesNG. Right: correct display of a table's borders in TablesNG.

In the example above, you can see that the leftmost blue cell was incorrectly
painting on top of the orange bottom-right cell as it could not have multiple
borders. In the re-architected implementation, this is solved, and the orange
border cell correctly paints on top of the blue one, allowing the second table
gap to have both blue and orange border lines.

This bug is now fixed in Chromium and Firefox.

## Sub-pixel geometry (table alignment)

Pixel alignment in tables is another interoperability issue that has been fixed
with TablesNG. Previously, the older engine always rounded graphics values to
the pixel. This meant that as you zoom in and out of the page, things would
shift, causing alignment problems. TablesNG fixes these alignment issues.

> [!WARNING]
> **Warning:** There is a [known bug](https://bugs.chromium.org/p/chromium/issues/detail?id=1201762) with table zoom and how borders are repainted. If you are testing this out, you may run into that.

## Rearchitecting the web

The Chrome team has not only been introducing new features to make web authoring
more robust, but they've also been working hard to improve existing APIs and
their compatibility. In fact, TablesNG is just one of many re-architecture
projects that this team has taken on over the past eight years. Others, though
not all of the projects, include:

- LayoutNG: a ground-up rewrite of all layout algorithms, for greatly improved reliability and more predictable performance.
- BlinkNG: a systematic cleanup and refactoring of the Blink rendering engine into cleanly separated pipeline phases. This allows for better caching, higher reliability, and re-entrant / delayed-rendering features such as [content-visibility](https://developer.chrome.com/content-visibility) and [container queries](https://developer.chrome.com/new-responsive).
- GPU Raster Everywhere: a long-term effort to roll out GPU rasterization on all platforms, whenever possible.
- Threaded scrolling and animations: a long-term effort to move all scrolling and non-layout-inducing animations to the compositor thread.

Keep a lookout for some more updates on these improvements and more!