By Tim King · Updated
Comparison Table CSS
Two-Column Plan Comparison With Ticks, Crosses and a Highlighted Winner
OneTask is free, with no sign-up, and built by one person.
If this tool saved you time, a coffee helps keep new ones coming.
How the Comparison Card Builder works
This comparison table CSS builder lays out plans or products side by side. "Which one should I pick?" is answered fastest by two columns and a list of ticks. Name the two options, type one feature per line with a value for each, choose which column to highlight and copy a real HTML table with row and column headers that screen readers can navigate.
Comparison table CSS: layout that answers the question
A comparison card is tabular data, so the generated markup is a <table> rather than a grid of
divs. That is not pedantry: a table gives screen reader users column and row headers announced
as they move between cells, and gives browsers a layout algorithm that keeps columns aligned no
matter what the cells contain. The card wrapper adds the rounded border and clips the corners.
Rows. Type each row as Label | value A | value B. Values of yes or no become a tick or
cross icon; anything else is printed as text, so you can mix "Unlimited" and "5 GB" with icons in
the same table. Ticks take the accent colour and crosses are faded, so a column full of ticks
reads as the better option at a glance.
Headers. The top row uses <th scope="col"> and the first cell of each body row uses
<th scope="row">. With both in place a screen reader entering a cell announces something
like "Pro, Custom domains, Yes", which is the whole comparison in one phrase. The
<caption> holds the card title and is read first.
Highlighted column. Choose Column A or B to tint that column with a light wash of the accent and add a three-pixel accent bar above its header. The tint is the accent at roughly 8% opacity, applied with an eight-digit hex colour, so it works on any background. Highlight the option you want people to choose, not the one that wins most rows.
Zebra stripes. Alternating row backgrounds help the eye track across a wide table. On a narrow two-column card they are optional; switch them off if the border rules are enough.
Widths. The label column takes 44% and the two value columns share the rest, centred. On
phones the card scrolls horizontally if it must; wrap it in an element with overflow-x: auto
so the page does not.
More than two options. The generator builds two because that is the common case and it fits
a card. For three or more options use the same table structure and add columns; the CSS
nth-child highlight rule just needs a different index.
FAQ
Should a comparison card be a table or a grid?
A table. It is tabular data with two dimensions — features by options — and only a table gives
assistive technology the row and column context for each cell. CSS grid can look identical but
loses that structure. The generated markup uses <th scope="col"> and <th scope="row"> so both
axes are announced.
How do I make tick and cross icons accessible?
Give each SVG role="img" and an aria-label of "Yes" or "No", as the generated icons do. Without
a label a screen reader either says nothing or reads "image", and the cell is meaningless.
Colour alone is not enough either — the tick and cross shapes differ so the meaning survives
without colour.
Can I add a third column?
Yes. Add another <th scope="col"> to the header row and a <td> to each body row. Reduce
the label column width to around 34% so three value columns fit, and update the nth-child
index in the highlight rules if you want a different column tinted.
How do I make the comparison work on mobile?
Wrap the card in an element with overflow-x: auto so a table that is too wide scrolls inside
the page rather than breaking the layout. Alternatively stack it: at a breakpoint set the table
and rows to display: block, hide the header and use td::before { content: attr(data-label) }
to label each value.
Why use eight-digit hex for the highlight tint?
Because it lets the tint derive from the accent colour without a separate colour input.
#ed880014 is the accent at about 8% opacity, so changing the accent recolours the tint too.
Eight-digit hex is supported in every current browser.
See also: all UI Components tools, Layout & Spacing, Shadows & Motion, Shapes & SVG, Forms & Inputs, Colour.
Related tools
Product Card Builder
E-commerce product cards with price, rating, badge and button.
Feature Grid Builder
Responsive icon-title-description feature grids for landing pages.
3D Tilt Card
Build a card that tilts in 3D toward the cursor with a glare.
404 Page Generator
Custom "page not found" HTML page with home link and search.
Accordion Builder
Build a smooth, accessible accordion from native details elements.