<app-compare-table> lays capabilities against options so a reader can settle a choice by scanning — the plan matrix under a pricing page, an “us vs them” table on a marketing site, a two-approach comparison in a doc.
It is an editorial table, not a data grid: the rows are authored, there is no sorting or paging, and the point is the comparison rather than the records.
Playground
Every control, live. Each change re-renders the real tag helpers on the server, so the markup underneath is the exact call that produced the table above it.
highlight tints only the matching columnSetting highlighted column to a column beyond the current column count is simply out of range — the table renders normally with no highlight, the same as picking "none".
Basic
The first column is the capability-name column and normally has an empty label. Each row's values line up with the columns after it.
A plan matrix
A value of true renders a tick, false a dash. Anything else renders as text.
caption is not decorationIt is rendered visually hidden and read by a screen reader before the table, which is how a non-sighted reader knows what is being compared. Without it the table announces as an unlabelled grid of ticks.
Highlighting a column
Mark the recommended option and its column is tinted throughout — header and cells. The reader's eye lands on it with no legend to read.
Recommending a tier
Highlight exactly one column. Two highlighted columns highlight nothing.
values is comma-separatedA Razor attribute cannot carry a collection, so the values are split on commas — a value that itself contains a comma needs the React component or a wider column label instead.
When to use
Use it when
A reader is choosing between two to four options on the same criteria.
The rows are authored capabilities, not records from a query.
Seeing the options side by side is what makes the choice obvious.
Reach for something else when
The rows are records to sort, filter or page. → app-data-table
You are showing the tiers themselves with prices and CTAs. → app-pricing-card
It is a list of facts about one thing. → app-info-list
Best practices
Do
Good example
Free
Pro
Single sign-on
-
Every row appears for every column, so the reader can read across. The row label names the capability in the customer's words.
Don't
Bad example
Free
Pro
SSO / SAML2 IdP federation
—
Y
Two highlighted columns highlight neither; internal jargon in the row label; and hand-typed “—”/“Y” instead of booleans loses the tick's shape cue.
Every option
The whole surface of the component, one cell per value — every cell-value type, every highlight combination, and the shapes a normal example doesn't cover.
cell value — what a row's values can hold
true → tick
true value
Plan
Feature
false → dash
false value
Plan
Feature
-
"text" → renders as-is
text value
Plan
Storage
50 GB
"" → empty cell
empty string value
Plan
Feature
a node value — React-only; Razor reaches the same outcome with plain text
text in place of a node
Plan
Uptime SLA
99.9%
column highlight
(default) no column highlighted
no highlight
Free
Pro
Single sign-on
-
app-compare-column highlight="true" — one tinted column
single highlight
Free
Pro
Single sign-on
-
two columns highlighted — neither reads as recommended
double highlight
Free
Pro
Single sign-on
-
caption
caption set — visually hidden, read by screen readers
Plan comparison
Plan
Feature
caption omitted — no <caption> element
Plan
Feature
content length
long row label wraps within the row-header column
long row label
Free
Pro
Single sign-on with SAML2 and SCIM-based automatic user provisioning
-
long cell value wraps within its column
long cell value
Free
Pro
Support
Community forum only best-effort
Dedicated 24×7 phone and email support
row grouping — not supported
No section/group rows in either surfacerows is a flat list — there is no group/section field on either the React prop or the <app-compare-row> tag helper. The nearest equivalent is a label-only row with blank values as a visual divider, shown below; for a genuinely sectioned comparison, render two adjacent <app-compare-table>s instead.
blank-value row as a section divider — values=","
section divider workaround
Free
Pro
Core
Reports per month
3
Unlimited
Collaboration
Single sign-on
-
class
class="pricing-table" — appended to the base compare-table class
class
Plan
Feature
Attributes
Attribute
Type
Default
Description
caption
string
—
Visually hidden description of what is being compared.
<app-compare-column> takes label and highlight. <app-compare-row> takes label and comma-separated values.