Pricing Table Patterns with Tailwind: Making Plans Easy to Compare
AI generated
tw
Tailwind CSS · Pricing · Conversion
Pricing Table Patterns with Tailwind
Making plans easy to compare without overwhelming the visitor

A pricing table is usually the moment interest turns into a purchase decision, and it deserves the corresponding amount of care in its design. Between a highlighted recommended plan, consistently styled feature checkmarks, and a working monthly/yearly toggle, there's more detail work involved than most off-the-shelf pricing table templates let on.

15 min read Recommended plan · feature comparison Monthly/yearly toggle

1. The anatomy of a good pricing table

A working pricing table consists of three to four clearly separated plan cards, each with a plan name, price, a short target-audience description, a feature list, and a single clear call-to-action button. The order of plans should consistently run from cheapest to most expensive, since users typically compare prices reading left to right.

Every feature row should appear in the same order across all plan cards, even when a cheaper plan doesn't offer a given feature at all, so the visual comparison works at a glance. Without a consistent row structure, the user has to actively jump back and forth between cards to figure out where each feature is included, making the decision unnecessarily harder.

The recommended plan should stand out from the other cards through several simultaneous visual signals: a slightly larger border or shadow via ring-2 ring-indigo-600, a small badge reading something like 'Most popular', and optionally a slightly larger scale for the whole card compared to its neighbors on wider screens.

It matters to use this emphasis sparingly, on a single card only, since highlighting several plans at once completely neutralizes the signal and puts the user right back in front of an equally weighted, hard decision. The emphasis should also remain recognizable without relying on color alone, through the badge and extra border weight, so it works clearly for color-blind users too.

3. Styling feature comparison checkmarks consistently

Checkmarks for included features and a visually distinct symbol for missing ones (a gray dash or a gray X rather than a red one) need to match exactly in size, spacing, and vertical alignment across every plan card. A red X for missing features quickly reads as unnecessarily negative and alarming, a muted gray communicates the same information more calmly.

The feature label itself should sit to the left of the symbol and wrap cleanly for longer feature names without the icon and text shifting vertically relative to each other. A flex items-start gap-3 layout with a fixed icon size via shrink-0 prevents the icon from drifting downward when text wraps to a second line and losing alignment with the first line.


<ul class="mt-6 space-y-3 text-sm text-gray-700">
  <li class="flex items-start gap-3">
    <svg class="mt-0.5 h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
      <path fill-rule="evenodd" d="M16.7 5.3a1 1 0 010 1.4l-7 7a1 1 0 01-1.4 0l-3-3a1 1 0 111.4-1.4l2.3 2.3 6.3-6.3a1 1 0 011.4 0z" clip-rule="evenodd" />
    </svg>
    Unlimited projects
  </li>
  <li class="flex items-start gap-3 text-gray-400">
    <svg class="mt-0.5 h-5 w-5 shrink-0" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
      <path fill-rule="evenodd" d="M4.3 4.3a1 1 0 011.4 0L10 8.6l4.3-4.3a1 1 0 111.4 1.4L11.4 10l4.3 4.3a1 1 0 01-1.4 1.4L10 11.4l-4.3 4.3a1 1 0 01-1.4-1.4L8.6 10 4.3 5.7a1 1 0 010-1.4z" clip-rule="evenodd" />
    </svg>
    Priority support
  </li>
</ul>

4. Implementing a monthly/yearly toggle with discount display

A toggle between monthly and yearly billing should be placed centrally above all plan cards, so the selection applies to every card at once rather than requiring the user to switch each card individually. A small badge right next to the toggle reading something like 'Save 20 percent' makes the financial benefit of the yearly option immediately visible, without the user having to do the math themselves.

Technically, the toggle can be implemented cleanly with Alpine.js by defining a single reactive state that determines whether the monthly or yearly price is shown per plan card. The transition between the two prices benefits from a short CSS transition on the number itself, so the switch reads as a smooth price change rather than an abrupt jump.

5. Responsive behavior with three or more plan columns

On wide screens, three to four plan cards fit comfortably side by side in a grid grid-cols-3 gap-8 layout, with the highlighted middle card able to poke slightly above the row through a small negative margin for extra visual priority. With exactly four plans, an even four-column grid usually works better than forcing a three-column split with an awkward fourth card wrapping to the next row.

Starting at the tablet breakpoint, the grid should drop to two columns via md:grid-cols-2 before collapsing to a single column on mobile, since three cards squeezed side by side at medium screen widths would either truncate text or shrink buttons down to an unusable size.

6. On mobile: stack the cards instead of squeezing a table

On mobile devices, plan cards are best shown fully stacked via grid-cols-1, with generous vertical spacing through gap-6 between cards, so each card stays clearly separated and fully readable on its own. The recommended plan should appear as the first card in this stacked view, not in its original middle position, so it's visible without a lot of scrolling first.

Long feature lists can additionally be collapsed by default on mobile and expandable through a 'Show all features' link, to shorten the page's initial scroll length. This interaction can be built with a few lines of Alpine.js through a simple x-show toggle state, without needing any JavaScript beyond Hyva or Alpine.

7. Accessibility in pricing tables

If a pricing table is implemented technically as a semantic HTML table rather than a card layout, scope="col" on the plan column headers and scope="row" on the feature names should be set, so screen readers can correctly announce the relationship between a feature and a plan. With the more common card layout, a clear heading hierarchy using h3 per plan name performs the same structural job instead.

Checkmark and X icons must never be the only source of information, since they're invisible to screen readers without accompanying text. Text hidden via sr-only, like 'Included' or 'Not included' next to each icon, ensures the information comes through fully even without visually perceiving the symbol.

8. Pricing psychology principles and how design supports them

The so-called decoy effect, where a deliberately less attractive middle plan makes the more expensive plan look better by comparison, only works when the visual design makes that price-to-feature relationship clearly visible. A generous, easy-to-scan presentation of the extra features in the pricier plan matters more here than pure price styling.

Charm pricing with numbers like '19' instead of '20' only works visually when the number itself is displayed large and dominant, while the currency symbol and billing period sit deliberately smaller and in a muted gray beside it. That size hierarchy draws the eye to the smaller number first, before the full context registers.

9. Common mistakes in pricing tables and how to avoid them

A frequent mistake is a feature list that's too long, overwhelming the user rather than informing them. A curated selection of the five to eight features that actually matter for the purchase decision almost always works better in practice than a full technical listing of twenty system details, which belongs on a separate comparison page instead.

Another common mistake is inconsistent button labels across plans, like 'Start free' on one plan and just 'Choose' on another, which makes the table feel disjointed. Consistent but slightly plan-specific wording, like 'Choose Starter' and 'Choose Pro', reads more professional while also making later A/B test analysis easier.

Plan Target audience Highlighting Monthly price
Starter Individuals, first tests None $9
Pro Small teams Recommended plan, badge and ring $29
Business Growing companies None $79
Enterprise Large organizations Custom quote instead of fixed price Contact sales

Mironsoft

Tailwind CSS architecture, design systems, and performance

Tailwind frontends that stay maintainable despite thousands of utility classes?

We review existing Tailwind projects for bloated class lists, inconsistent design tokens, and unused CSS remnants, then build a design system that scales cleanly instead of getting messier with every component.

Design System Review

Checking tokens, spacing scale, and component consistency for maintainability.

Performance Optimization

Systematically reducing CSS bundle size, purge configuration, and load times.

Component Architecture

Building reusable, well-structured components instead of sprawling class lists.

10. Summary

Pricing Tables with Tailwind: Key Takeaways

Recommended plan

Highlight only one card at a time, otherwise the signal effect neutralizes itself.

Feature checkmarks

Fixed icon size with shrink-0 so wrapped text never shifts the symbol out of alignment.

Toggle discount

Place a badge with a concrete percentage right next to the monthly/yearly toggle.

Mobile order

Show the recommended plan as the first card on mobile, not in its original middle position.

11. FAQ: Pricing Tables with Tailwind: Key Takeaways

1How many plans should a pricing table show at most?
Three to four plans is the proven sweet spot. More options measurably make the decision harder, since users often postpone choosing altogether when faced with too many equally weighted alternatives.
2Should the recommended plan always be the most expensive one?
No, the recommended plan is usually the middle one, offering the best value for the largest target audience. Highlighting the most expensive plan tends to feel off-putting to most users.
3How do you implement the monthly/yearly toggle technically?
The simplest way is with Alpine.js through a single reactive boolean state that determines which price is shown per plan card. A short CSS transition on the number makes the switch feel smooth rather than abrupt.
4How many features should each plan card list?
Five to eight curated, purchase-decision-relevant features is usually enough. A full technical listing of every detail belongs on a separate, more detailed comparison page instead.
5How should pricing tables be displayed on mobile?
Best fully stacked in a single column rather than squeezed side by side, with the recommended plan as the first card so it's visible without a lot of scrolling first.
6How do you make pricing tables accessible?
Checkmark and X icons need accompanying sr-only text like 'Included' or 'Not included', since icons alone carry no information for screen readers.
7What's the decoy effect in pricing tables?
A deliberately less attractive middle plan makes the more expensive plan look better by direct comparison. The effect only works when the feature differences are presented clearly and visually.
8Should all buttons in a pricing table look the same?
The recommended plan's button should stand out in color as the primary action, while the other plans' buttons can be styled more subtly, keeping attention on the recommended plan.
9How do you handle very different feature lists between plans?
All feature rows should appear in the same order across every card, even when a cheaper plan lacks a given feature, so the row-by-row comparison keeps working.
10Is an enterprise plan without a fixed price worth having?
Yes, for individually negotiated large-account contracts, 'Contact sales' instead of a fixed price is common and sensible, since the actual price depends heavily on usage scope and contract length.