Blog Tutorial

Building accessible pricing tables in WordPress with core blocks

How to structure multi-tier pricing tables using semantic HTML, correct heading hierarchies, and accessible contrast in the WordPress block editor.

Pricing tables are among the most visited sections on a commercial website, yet they frequently fail basic web accessibility audits. When built with visual drag-and-drop builders or unreviewed block kits, pricing cards often use visual-only headings, non-semantic icon lists, and unlabelled call-to-action buttons that confuse screen reader users and fail keyboard navigation checks.

You can construct clean, fully accessible pricing grids in WordPress using only standard core blocks.

Common accessibility failures in pricing layouts#

Audits of commercial pricing components consistently expose three critical structural defects:

  1. Broken heading hierarchies: Tier names (like "Starter" or "Enterprise") are often styled using <span> or <p> tags with large inline font sizes rather than proper <h3> elements, preventing screen readers from building an outline of available tiers.
  2. Ambiguous call-to-action buttons: Multiple buttons on the same page labelled simply "Get started" or "Buy now" provide zero context when a screen reader navigates by interactive elements.
  3. Low-contrast featured badges: "Popular" or "Best value" badges placed on tinted background bands frequently fall below the WCAG AA minimum contrast ratio of 4.5:1 for standard text.

Structuring the semantic markup#

An accessible three-tier pricing grid relies on a clear container hierarchy:

  1. A parent section with an <h2> introducing the pricing options.
  2. A columns block where each column represents one distinct tier.
  3. Inside each column, an <h3> naming the plan tier, followed by the price, a semantic unordered list (<ul>) for included features, and a uniquely identified button.

Here is the clean core block structure for an individual tier card:

<!-- wp:group {"className":"pricing-card","style":{"spacing":{"padding":{"top":"var:preset|spacing|40","bottom":"var:preset|spacing|40","left":"var:preset|spacing|40","right":"var:preset|spacing|40"}}},"layout":{"type":"flex","orientation":"vertical"}} -->
<div class="wp-block-group pricing-card">
  <!-- wp:heading {"level":3,"fontSize":"large"} -->
  <h3 class="wp-block-heading has-large-font-size">Professional</h3>
  <!-- /wp:heading -->

  <!-- wp:paragraph {"style":{"typography":{"fontSize":"2.5rem","lineHeight":"1"}}} -->
  <p style="font-size:2.5rem;line-height:1"><strong>$49</strong> <span style="font-size:1rem;color:var(--wp--preset--color--contrast-muted)">/ month</span></p>
  <!-- /wp:paragraph -->

  <!-- wp:paragraph {"fontSize":"small"} -->
  <p class="has-small-font-size">For growing teams requiring advanced workflow controls and priority support.</p>
  <!-- /wp:paragraph -->

  <!-- wp:list {"className":"pricing-features"} -->
  <ul class="wp-block-list pricing-features">
    <!-- wp:list-item -->
    <li>Unlimited active projects</li>
    <!-- /wp:list-item -->
    <!-- wp:list-item -->
    <li>Advanced permission controls</li>
    <!-- /wp:list-item -->
    <!-- wp:list-item -->
    <li>Standard integrations</li>
    <!-- /wp:list-item -->
  </ul>
  <!-- /wp:list -->

  <!-- wp:buttons {"layout":{"type":"flex","justifyContent":"center"}} -->
  <div class="wp-block-buttons">
    <!-- wp:button {"width":100} -->
    <div class="wp-block-button has-custom-width wp-block-button__width-100">
      <a class="wp-block-button__link wp-element-button" href="/checkout/?plan=pro" aria-label="Sign up for the Professional plan at $49 per month">Get Professional</a>
    </div>
    <!-- /wp:button -->
  </div>
  <!-- /wp:buttons -->
</div>
<!-- /wp:group -->

Adding screen-reader context to CTA buttons#

When a visually impaired user tabs through a webpage, their screen reader announces the link text in isolation. If every button in the grid announces "Get started", the user cannot determine which tier they are selecting without re-reading the surrounding card.

Adding an aria-label attribute directly to each button link solves this immediately:

<a class="wp-block-button__link" href="/signup" aria-label="Sign up for the Professional plan at $49 per month">Get started</a>

Sighted users see the concise "Get started" label on the visual button, while assistive technologies announce the complete context including the plan name and price.

Verifying contrast and keyboard focus#

Before deploying a pricing section:

  1. Test keyboard tab order: Press Tab repeatedly to cycle through each interactive element. Ensure the focus ring is clearly visible around each tier button and follows a logical left-to-right sequence.
  2. Inspect contrast ratios: Use Chrome DevTools or Lighthouse to audit contrast between text, badges, and card backgrounds. Accent cards with coloured backgrounds must maintain at least a 4.5:1 contrast ratio against body text and 3:1 against UI borders.

Pattern Paste provides accessible block patterns, including verified pricing layouts like pricing-single and pricing-tiers tested for WCAG AA compliance. Browse the entire library.

From the library

Read next

All posts