Skip to content
Site volume
Colourway

Components

ComparisonTable

Tiers side by side, with a one-tier switcher on phones that works without JavaScript.

  • Beta
  • Reading layer
  • Server component
  • Since 0.1.0
  • Press check
Import from@maxgrits/overprint-react/comparison-table
On this page

Example#

Look of this example
What each tier includes
Templated2 to 4 weeksSemi-customMost picked4 to 6 weeks
Build
PagesUp to 5Up to 12
Your own layoutNot includedIncluded
Live render of examples/comparison-table/basic.tsx

Usage#

Use a comparison table for pricing tiers or plans, two to five of them, compared feature by feature. On desktops it is a real table with sticky tier heads; below the md width it switches to one tier at a time with a segmented control, without JavaScript.

  • Tiers take a name, a note (such as the timeline), an optional CTA and recommended, which draws a 3 px ink box around the column and a badge with recommendedLabel.
  • Values. true prints a check with "Included" for screen readers, false a dash with "Not included", and strings print as text: prices stay literal.
  • Groups split the rows under group headings, such as Build and Care.

Anatomy#

What each tier includes
Templated2 to 4 weeksSemi-customMost picked4 to 6 weeks
Build
PagesUp to 5Up to 12
Your own layoutNot includedIncluded
The parts of examples/comparison-table/basic.tsx, numbered:
  1. Tier headName and note; sticky under the header..mk-comparison-table-tier
  2. RecommendedA badge, plus a 3 px ink box around the column..mk-comparison-table-badge
  3. GroupA row group heading..mk-comparison-table-group
  4. FeatureThe row's name, with an optional description..mk-comparison-table-feature

Volume#

Reading layer: identical at every volume.

  • Quiet

    What each tier includes
    Templated2 to 4 weeksSemi-customMost picked4 to 6 weeks
    Build
    PagesUp to 5Up to 12
    Your own layoutNot includedIncluded

    Docs, forms, legal and long reads. Flat inks, no art in motion.

  • Studio

    What each tier includes
    Templated2 to 4 weeksSemi-customMost picked4 to 6 weeks
    Build
    PagesUp to 5Up to 12
    Your own layoutNot includedIncluded

    The site default. Art on its own plates, one display moment per view.

  • Press

    What each tier includes
    Templated2 to 4 weeksSemi-customMost picked4 to 6 weeks
    Build
    PagesUp to 5Up to 12
    Your own layoutNot includedIncluded

    Hero moments, covers and campaigns. Halftone fields and the second ink.

  • Rave

    What each tier includes
    Templated2 to 4 weeksSemi-customMost picked4 to 6 weeks
    Build
    PagesUp to 5Up to 12
    Your own layoutNot includedIncluded

    Launches, posters and the 404. Every ink, and the words still win.

Content#

  • Tier names are short and ordered by size: "Templated", "Semi-custom", "Custom".
  • Features are nouns people look for: "Pages", "Your own layout".
  • Strings beat ticks when the answer is a quantity: "Up to 12", not a check mark.
  • The recommended label is honest: "Most picked" if it is, never "Best value" unless you can show it.

Do and don't#

Do

What each tier includes
Templated2 to 4 weeksSemi-customMost picked4 to 6 weeks
Build
PagesUp to 5Up to 12
Your own layoutNot includedIncluded

Few tiers, the differences that matter.

Don't

Five tiers, thirty rows of ticks and no prices.

A wall of ticks.

A comparison should make the choice easier. Rows that are the same in every tier add reading without adding information.

Accessibility#

  • A real table: tier heads are column headers, groups are row groups, features are row headers.
  • Checks and dashes carry the words "Included" and "Not included" for screen readers.
  • On phones the switcher's native radios pick the tier; hidden columns leave the accessibility tree.

Props#

PropTypeDefaultDescription
caption requiredstringnone
tiers requiredreadonly ComparisonTier[]none2 to 5 tiers.
groups requiredreadonly ComparisonGroup[]none
recommendedLabelstringnoneThe recommended tier's badge (no default copy).
switcherLabelstring"Show tier"The switcher's name (default "Show tier").
switcherNamestringfrom the caption and a per-instance id, so two tables with one caption on a page keep their own checked tierThe switcher's radio name (default from the caption and a per-instance id, so two tables with one caption on a page keep their own checked tier).
includedLabelstringnoneWords for `true` and `false` (defaults "Included", "Not included").
notIncludedLabelstringnone

Plus 279 React and DOM attributes passed through to the root element (className, ref, aria-*, event handlers and the rest). Generated from ComparisonTableProps in packages/overprint-react/src/reading/comparison-table/comparison-table.tsx.

Tokens#

System tokens (11)

Its own properties (1)

  • --mk-header-h

Scanned from its CSS at build and checked against its registry entry; 6 read but not declared there.

Changelog#

Arrived in 0.1.0.

0.1.024 October 2026

  • MinorreactSection with its plate and Art slot, Plate, VolumeScope, PageHero, SectionHead, Eyebrow, Card, LineCard, InfoPanel, Stack, Cluster, Grid, Container, Main, Rule and the FittedLine client fitter; Navbar with the NavDisclosure mega panels, Footer, FooterMap, BuildStamp, SkipLink, ActionDock and VisitorControls; the Table parts, ComparisonTable with the one-tier switcher, SpecStrip, Numeral, Stat, StatGroup, StatusChip, Badge and ScoreDial; Prose with mdxComponents, Quote, CodeBlock with CopyButton, Figure, ScreenshotFrame and PhoneFrame; and the brand: the three evolved 2 × 2 options in markGeometry (a Overprint by default, b Paper seam, c Key block) with the pixel-snapped px mode and the one-ink seam variant, logoGeometry with the 1x clear-space frame, Mark, Wordmark, Logo, MaxosMark and LineBadge. Read the whole entry
  • PatchreactA ruler range keeps its two values apart, a slider's end figures stay inside it, ComparisonTable and the segmented ThemeToggle name their radios per instance (two on a page no longer uncheck each other), and a Stamp's second line wraps, with the big stamp at 0.6× below 30rem. Read the whole entry