Why Notifio’s Comparison Pages Aren’t Real Tables
Resumen
Pixel’s announcement examines an audit of 38 Notifio pages, highlighting five comparison pages with 49 rows and 811 words but no table elements or semantic table roles. It matters because the markup behind comparison content can affect accessibility and how clearly readers understand side-by-side claims.
DEV Community
49 rows of comparison, zero table elements, and 811 words of it carrying five full stops in total
I pulled all 38 pages of notifio.app and counted words and sentences in the visible text, to see where the site's weight actually sits: 36,947 visible words 2,001 sentences 18.5 words per sentence on average thickest page: /terms at 2,440 words thinnest page: /download at 149 words, with /pricing second at 344 That last pair is worth a post of its own some day, because the two pages that have to actually sell something are the two thinnest on the site. But the thing that stopped me was the sentence-length table. The longest sentence on notifio.app, by my splitter, was 202 words. The next three were 191, 168 and 150. The fifth was 141 words and sat in the terms of service, which is where you expect to find a 141-word sentence. The top four were not sentences. They were the comparison tables, and they are not tables. There is no table in the comparison table $ curl -s https://notifio.app/compare/rentbird | grep -c '<table'
0
$ curl -s https://notifio.app/compare/rentbird | grep -c 'role="'
0
No
, no , no role="table", no
. The side-by-side on all five comparison pages is a CSS grid of div and p elements, 13 grid containers on the page. I counted the rows and their honesty flags last month in 49 rows in our comparison tables, 13 of them say the competitor wins. I counted the argument prose in a required field made us concede on every comparison page. Both times I read the data and never the markup carrying it. Measured per page, taking the text of just the side-by-side section: Page Rows Words in the section Sentence-ending full stops /compare/rentbird 10 196 1 /compare/visualping 11 185 1 /compare/rentslam 10 162 1 /compare/stekkies 10 144 1 /compare/rentola 8 124 1 811 words, 49 rows, and five full stops between them. Each page's single stop is the caption underneath: "Brighter text marks whichever side we think genuinely wins that row, including the rows where it is not us." Flattened, the Rentbird one begins like this: Rentbird Notifio Price Rentbird: €29 for one month, €49 for three Notifio: £20 once, forever What happens when you stop paying Rentbird: Alerts stop Notifio: Nothing, since the licence does not expire The rival's name appears twelve times in the extracted text of a ten-row table. That is not a bug in my extractor. It is two labelling systems in one document. Why it is divs, and why the divs are not lazy // src/app/compare/[target]/page.tsx
{target.name}
Notifio
function Cell({ label, value, won }: { label: string; value: string; won: boolean }) {
return (
{${label}:}
{value}
);
}
There are two sets of labels and each is switched off at the breakpoint where the other works. On a wide screen you get a column header row and the per-cell prefixes are display: none. On a phone the header row is display: none and each cell introduces itself, "Rentbird: €29 for one month", which is the only way a three-column row survives being stacked vertically. 98 of those hidden prefixes exist across the five pages. And the accessibility of that is better than I expected when I started writing this. Tailwind's hidden is display: none, and display: none is hidden from assistive technology, not just from eyes. So a screen reader at desktop width hears the column header and no prefix; at phone width it hears the prefix and no header. The labels follow the breakpoint. This is not the classic bug where a visually hidden label gets announced on top of a visible one. What is actually lost Two things, and the second one is the one I had not thought about. Table semantics. Without , a screen reader user gets 49 paragraphs in a row. There is no "column 2 of 3", no row navigation, no way to walk down one product's column and hear only its answers. On...

Powered by Readybot.io