Comparison Table — Free HTML CSS Pricing Snippet

Comparison Table · Tables · Plain HTML & CSS · Live preview

Share & Support

What's included

Features

.featured class on every td in a column creates a continuous accent border top-to-bottom
.popular-badge: position absolute top: -12px + translateX(-50%) centering trick
.section-row with colspan="4" spans full width as a labelled feature group divider
.yes (✓ green) and .no (✗ grey) indicators — grey chosen over red to reduce alarm on unchecked cells
plan-btn.solid and .outline variants for primary (featured) and secondary CTA differentiation
overflow-x: auto on .table-scroll — horizontal scroll on narrow screens, no layout break
tbody tr: last-child td.featured adds bottom border to close the featured column box
Pure HTML and CSS — no JavaScript required
Export as HTML file, React JSX component, or React + Tailwind CSS
Live split-pane editor — preview updates as you type

About this UI Snippet

Comparison Table — Featured Column, Section Row Dividers & Check/Cross Indicators

Screenshot of the Comparison Table snippet rendered live

A feature comparison table is the most effective layout for communicating the difference between product tiers side by side. Instead of separate pricing cards, a comparison table lets users scan any specific feature across all plans in one eye movement — making the upgrade decision faster and clearer. This snippet provides a complete HTML and CSS comparison table with a featured column accent, section row dividers, check and cross indicators, plan CTA buttons, and horizontal scroll for mobile. No JavaScript required.

How the featured column accent works

The continuous vertical column highlight is achieved by applying the .featured class to every td in the Pro column — not just the column header. Each .featured td gets border-left: 1.5px solid #6366f1 and border-right: 1.5px solid #6366f1. The last row's .featured td also gets border-bottom. The header th.featured gets the same left and right borders. Together these create a continuous bordered box from the very top of the table to the very bottom, enclosing the entire Pro column, without any JavaScript or absolute-positioned overlay.

The .popular-badge inside the featured header uses position: absolute; top: -12px; left: 50%; transform: translateX(-50%) — the classic centering trick that floats the badge above the column header regardless of text length.

Why grey for "not included" instead of red

The .no indicator uses light grey (✗ in #94a3b8) rather than red. On a feature comparison table, most cells in the lower-tier columns will be "not included." Red is an alarming colour — a table full of red crosses makes the lower tiers look broken or dangerous rather than simply limited. Grey communicates "not available at this tier" without negative connotation, reducing visual noise while still making the tier difference clear.

Section row dividers

.section-row cells use colspan="4" to span the full table width and render a category label — Core, Features, Enterprise — in uppercase with a light background. These dividers group related feature rows into scannable sections. On a long feature list, section dividers are essential for preventing the table from becoming an undifferentiated wall of checkmarks.

Responsive horizontal scroll

A five-column comparison table is inherently wide. The .table-scroll wrapper uses overflow-x: auto so the table scrolls horizontally on narrow screens without breaking the fixed column widths. The scrollbar appears only when needed.

Adapting to your product

Replace plan names, prices, and feature rows directly in the HTML. Move the .featured class to any column. Add section-row tr elements to introduce new feature groups. For an annual billing toggle, wire in the Pricing Toggle snippet and update .plan-price textContent on switch — the table structure is unchanged.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to puzzle out why the featured column border never has gaps by staring at the table markup. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why the featured class has to be applied to every single td in the column rather than to a wrapper element, and why that only works cleanly with border-collapse set on the table. The same assistant can help optimize it — for instance asking whether a very long feature list would benefit from sticky positioning on the feature-label column so it stays visible while scrolling horizontally on mobile. It's also useful for extending the table: ask it to add a monthly/annual pricing toggle that swaps the price text without changing the table structure, generate the whole table from a plans/features data array instead of hand-written markup, or add row-level tooltips explaining technical feature names. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a pricing feature-comparison table in plain HTML and CSS only — no JavaScript required, no table libraries.

Requirements:
- A standard HTML table with border-collapse: collapse, one header column for feature names and one column per pricing plan, each plan header containing a name, a price, and a call-to-action link/button.
- One plan column must be visually "featured": apply a distinct background and a left/right border to every single td in that column (not just the header, not a wrapper div), plus a matching border on the header cell and a bottom border on the very last row's cell in that column, so the accent forms one unmistakably continuous box running from the top of the table to the bottom with zero gaps between rows.
- A "most popular" badge on the featured column's header, centered horizontally over the column using absolute positioning and a translateX(-50%) transform so it stays centered regardless of the badge text length.
- Section-divider rows that span the full table width (colspan across all columns) with a distinct background and uppercase label, used to group related feature rows (e.g. "Core", "Features", "Enterprise") so a long feature list doesn't read as one undifferentiated wall of rows.
- Included/excluded feature values must be rendered as a checkmark and a cross, where the "excluded" mark uses a muted gray rather than red, since a column full of red crosses reads as broken rather than simply a lower tier.
- Wrap the table in a container with overflow-x: auto so it can be scrolled horizontally on narrow viewports without breaking the column widths or wrapping cell content awkwardly.

Step by step

How to Use

  1. 1
    Update plan names and pricesIn the HTML panel, change the plan name text, price number, and /mo period label in each th.plan-head. Update each plan-btn link text and href to your checkout URLs.
  2. 2
    Update feature row valuesChange each td content — text values for quantitative features, or a span with class="yes" for included and class="no" for excluded features. The colour is applied automatically by the class.
  3. 3
    Add or remove a plan columnAdd a new th in the thead and a matching td in every tbody and tfoot row. The table width distributes automatically. Remove a plan by deleting its th and all its td elements.
  4. 4
    Change which column is featuredRemove .featured from all current td elements in the middle column. Add .featured to all td elements in the new column you want to highlight. Move the .popular-badge div to that column header.
  5. 5
    Add new feature rowsCopy any existing tr and paste it inside the tbody. Change the .feature-label td text and the td values for each plan. Place it under the correct .section-row group to keep features organised by category.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component mapping a plans array and features array, or "Tailwind" for a React + Tailwind CSS version.

Real-world uses

Common Use Cases

SaaS pricing page feature comparison
The canonical SaaS pricing page pattern — three tiers side by side with the recommended Pro plan highlighted. Pair it with standalone pricing cards and a full pricing page layout. The feature matrix lets users answer "do I need Pro?" by scanning down the feature column they care about most.
Software edition and tier comparisons
Compare Basic, Professional, and Enterprise editions with Core, Features, and Enterprise section dividers. Section rows group related features (Collaboration, Security, Support) so users can jump to the section relevant to their decision.
Agency and service package comparisons
Show Starter, Growth, and Scale service packages with deliverables listed as features. The table format answers "what exactly do I get at each tier?" far more clearly than bullet point lists on separate pages.
Learn continuous column highlighting with CSS
The featured column technique applies .featured to every td in the column. Edit the border-color and background values in the CSS panel to understand why applying the class to each individual cell — rather than an overlay div — creates a robust column border that respects row heights.
Your product versus competitor comparison pages
Show your product as the featured column with a "Best choice" badge. List competitor columns without the accent. Use .yes/.no indicators to show where your product wins across each feature row.
Hardware, device, and technical spec comparisons
Compare product models by processor speed, RAM, storage capacity, battery life, and weight. Replace .yes/.no spans with plain text values in spec rows. The table structure and featured column technique work identically for numerical specifications.

Got questions?

Frequently Asked Questions

The .featured class is applied to every individual td in the Pro column — not just the header or a wrapper div. Each cell gets border-left and border-right at 1.5px. Because table cells are adjacent with no gap between them (border-collapse: collapse), the borders line up perfectly to create one continuous vertical line. The last row adds border-bottom to close the box, and the header adds the top and left/right borders.

Move the .popular-badge div from the current featured th to the new th. Also move the .featured class from every td in the current column to every td in the new column — all tbody cells and the tfoot cell. The badge positioning is relative to its parent th, so it automatically centres over the new column.

See the Pricing Toggle snippet for the complete toggle implementation. Add the toggle HTML above the table. In JS, define a monthly array and an annual array indexed by plan column. On switchBilling(), update each .plan-price span textContent. The table layout does not change — only the price text updates.

The .table-scroll wrapper with overflow-x: auto already handles horizontal scrolling on narrow screens — the table maintains its full column widths and the user scrolls horizontally. For a fully stacked mobile layout, use @media (max-width: 600px) { .comp-table { display: block } tr, td { display: block } thead tr { display: none } } and add data-label attributes to cells for column context.

Yes. Click "JSX" to download. In React, define a plans array (with name, price, featured, buttonLabel) and a features array (with label, section, and a value per plan). Map plans to th columns and features to tr rows. Apply conditional className for .featured based on the plan.featured property. For Next.js, pass plans and features as props from getStaticProps.

Use the CSS Tooltip snippet from this library. Add data-tip="Explanation text" to each .feature-label td. Paste the tooltip CSS rules. The tooltip appears on hover entirely through CSS — no JavaScript needed. This is especially useful for technical feature names that need a one-sentence explanation.