KKUONIDesign System

Components

Comparison Table

Beta

Side-by-side feature comparison for holiday packages, room types, or board basis options. Tick/cross cells and a highlighted recommended column guide decision-making.

FeatureSelf CateringHalf BoardAll InclusiveRecommended
Breakfast
Dinner
Drinks included
Snacks all day
Airport transfers

Purpose

The ComparisonTable is a structured grid that places multiple options side-by-side so customers can evaluate feature differences at a glance. It is most useful when:

  • Board basis comparison — Self Catering vs Half Board vs All Inclusive
  • Room type comparison — Standard Room vs Garden Villa vs Overwater Bungalow
  • Holiday package tiers — Essential vs Premium vs Luxury
  • Destination feature comparison — comparing what's included at two resorts

A highlighted column (with a "Recommended" chip) draws attention to the option Kuoni specialists suggest. A sticky first column keeps feature labels visible when the table scrolls horizontally on small screens.

Usage

Reach for ComparisonTable when a customer must weigh two or more named options against the same set of features — board basis, room type, or package tier. When you only need to list what one single option includes (with no side-by-side comparison), use FeatureList instead; it is lighter weight and doesn't force a grid.

ComparisonTable typically sits on product detail pages below the hero, in quote summaries where specialists present alternatives, or inside a modal/drawer triggered by a "Compare" action from a listing page.

Anatomy

FeatureStandardPremiumRecommended
Airport transfers
MealsBreakfastAll meals
Spa access
  1. 1
    Header rowColumn labels in a grey-50 header row. Highlighted column shows in teal-50 with a "Recommended" chip.
  2. 2
    Feature column (sticky)Leftmost column with feature names. Stays visible on horizontal scroll via sticky positioning.
  3. 3
    Included cell (tick)Green Check icon (text-success) with aria-label="Included".
  4. 4
    Excluded cell (cross)Grey X icon (text-grey-300) with aria-label="Not included".
  5. 5
    N/A cell (dash)Grey dash for features that are not applicable to the option.
  6. 6
    Text cellString values are rendered as plain text in kuoni-dark. Used for prices, quantities, or partial inclusions.
  7. 7
    Feature noteOptional secondary note below the feature name in grey-400. e.g. "(subject to availability)".

Variants

Boolean tick/cross (most common)

Set cell values to true (green tick), false (grey cross), or null (grey dash).

FeatureStandard RoomDeluxe RoomVilla SuiteRecommended
Sea view
Private pool
Butler service
Outdoor shower
King bed

Mixed content (text + boolean)

String values render as text cells. Use for quantities, grade descriptions, or partial inclusions.

FeatureEssentialLuxuryRecommended
Nights710
Star rating4★5★
Board basisBed and BreakfastAll Inclusive
Airport transfers
Excursions2 included

With feature notes

Add a note to any row for secondary context under the feature name.

FeatureHalf BoardFull BoardRecommended
Dinner

Included each evening

Lunch

Subject to availability

Afternoon tea

Best practices

Do

Highlight one column as recommended when there is a clear best-value or most-popular option.

'All Inclusive' highlighted with a Recommended chip draws the eye to the best value option.

Don't

Highlight more than one column in the same table.

Two highlighted columns compete for attention — neither stands out.

Do

Order rows from most important to least important for the typical customer.

Rows in order of perceived importance let users scan the most important features first.

Don't

Order rows alphabetically by feature name.

Alphabetical order puts minor amenities above key inclusions like meals and transfers.

Do

Use string cell values for nuanced inclusions that a simple tick or cross would misrepresent.

Use text values like 'Bed and Breakfast' or '7 nights' for features that are not simply included or excluded.

Don't

Use a tick for features that have partial or variable inclusion without clarifying text.

A tick for 'Meals' could mean breakfast-only or all-inclusive — text clarifies.

Do

Always provide a caption prop describing what the table is comparing.

The caption prop is read by screen readers as the table's accessible name.

Don't

Omit the caption on comparison tables.

An anonymous table gives screen reader users no context for what is being compared.

Props

PropTypeDefaultDescription
columns*Array<{ label: string; value: string; highlighted?: boolean }>Column definitions. value is used as the key in each row's values object. highlighted=true marks the recommended column in teal.
rows*Array<{ feature: string; note?: string; values: Record<string, boolean | string | null> }>Row definitions. values is a map of column.value to cell content. true=tick, false=cross, null=dash, string=text.
highlightColumnstringAlternative to column.highlighted — pass the column value to highlight it programmatically.
captionstringScreen-reader-only table caption. Describes what is being compared.
stickyFirstColumnbooleantrueMakes the feature name column sticky on horizontal scroll.
classNamestringAdditional Tailwind classes on the scroll wrapper.

Accessibility

Table semantics

ComparisonTable renders a proper <table> with <thead>, <tbody>, <th scope="col"> headers, and <td> cells. This gives screen reader users full table navigation (read row, read column header, navigate by cell).

Cell icons

Tick, cross, and dash icons each have aria-label:

  • Tick: aria-label="Included"
  • Cross: aria-label="Not included"
  • Dash: aria-label="Not applicable"

The icons themselves are aria-hidden="true" so only the aria-label is announced.

Screen reader navigation

Screen reader users can navigate with:

  • Arrow keys → move between cells
  • Read table → announces cell value + row header + column header

Sticky column on mobile

The sticky first column uses position: sticky with a background that matches the row stripe, preventing ghost overlapping of content when scrolling horizontally.

  • FeatureList — use for a single option's inclusions/exclusions when there is nothing to compare side-by-side.
  • Chip — the "Recommended" indicator on a highlighted column is a Chip.