21 CSS Pricing Sections03 / 21
Feature Comparison Table
A real <table> with proper <th scope>, sticky header row, and check / dash cells comparing four plans across nine features. Cyan accent on the recommended column. Mobile fallback collapses to a stacked card list under 720px.
Published
The code
<section class="ps-03" aria-label="Plan comparison">
<header class="ps-03__head">
<h2>Compare every feature.</h2>
<p>Pick the column that matches what you ship today.</p>
</header>
<div class="ps-03__scroll">
<table class="ps-03__tbl">
<thead>
<tr>
<th scope="col" class="ps-03__fc">Feature</th>
<th scope="col">Free<br /><span>$0</span></th>
<th scope="col" class="ps-03__rec">
<span class="ps-03__pill">Recommended</span>Pro<br /><span>$24</span>
</th>
<th scope="col">Team<br /><span>$48</span></th>
<th scope="col">Enterprise<br /><span>Contact</span></th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Projects</th>
<td>1</td>
<td class="ps-03__rec">10</td>
<td>50</td>
<td>Unlimited</td>
</tr>
<tr>
<th scope="row">Storage</th>
<td>500 MB</td>
<td class="ps-03__rec">10 GB</td>
<td>50 GB</td>
<td>500 GB</td>
</tr>
<tr>
<th scope="row">Custom domain</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Team roles</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Priority support</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">SSO & SAML</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Audit logs</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">99.99% SLA</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Dedicated CSM</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row" class="ps-03__fc"></th>
<td><a class="ps-03__cta" href="#free">Get started</a></td>
<td class="ps-03__rec">
<a class="ps-03__cta ps-03__cta-pri" href="#pro">Choose Pro →</a>
</td>
<td><a class="ps-03__cta" href="#team">Choose Team</a></td>
<td><a class="ps-03__cta" href="#ent">Talk to sales</a></td>
</tr>
</tfoot>
</table>
</div>
</section><section class="ps-03" aria-label="Plan comparison">
<header class="ps-03__head">
<h2>Compare every feature.</h2>
<p>Pick the column that matches what you ship today.</p>
</header>
<div class="ps-03__scroll">
<table class="ps-03__tbl">
<thead>
<tr>
<th scope="col" class="ps-03__fc">Feature</th>
<th scope="col">Free<br /><span>$0</span></th>
<th scope="col" class="ps-03__rec">
<span class="ps-03__pill">Recommended</span>Pro<br /><span>$24</span>
</th>
<th scope="col">Team<br /><span>$48</span></th>
<th scope="col">Enterprise<br /><span>Contact</span></th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Projects</th>
<td>1</td>
<td class="ps-03__rec">10</td>
<td>50</td>
<td>Unlimited</td>
</tr>
<tr>
<th scope="row">Storage</th>
<td>500 MB</td>
<td class="ps-03__rec">10 GB</td>
<td>50 GB</td>
<td>500 GB</td>
</tr>
<tr>
<th scope="row">Custom domain</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Team roles</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Priority support</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">SSO & SAML</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Audit logs</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">99.99% SLA</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Dedicated CSM</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row" class="ps-03__fc"></th>
<td><a class="ps-03__cta" href="#free">Get started</a></td>
<td class="ps-03__rec">
<a class="ps-03__cta ps-03__cta-pri" href="#pro">Choose Pro →</a>
</td>
<td><a class="ps-03__cta" href="#team">Choose Team</a></td>
<td><a class="ps-03__cta" href="#ent">Talk to sales</a></td>
</tr>
</tfoot>
</table>
</div>
</section>.ps-03 {
padding: clamp(28px, 5vw, 56px) clamp(16px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #06141a;
color: #e0f2f7;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-03__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 36px);
}
.ps-03__head h2 {
font-size: clamp(22px, 3.2vw, 32px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0 0 8px;
color: #f1fbff;
}
.ps-03__head p {
color: #88a8b3;
margin: 0;
font-size: 14px;
}
.ps-03__scroll {
overflow-x: auto;
overflow-y: visible;
-webkit-overflow-scrolling: touch;
max-width: 980px;
margin: 0 auto;
padding-top: 14px;
}
.ps-03__tbl {
width: 100%;
border-collapse: separate;
border-spacing: 0;
font-size: 13.5px;
min-width: 720px;
}
.ps-03__tbl th,
.ps-03__tbl td {
text-align: center;
padding: 14px 12px;
border-bottom: 1px solid rgba(34,211,238,0.1);
}
.ps-03__tbl thead th {
font-size: 14px;
font-weight: 700;
color: #cfeaf2;
background: #0c1f27;
position: relative;
}
.ps-03__tbl thead th span:not(.ps-03__pill) {
display: block;
font-size: 13px;
font-weight: 500;
color: #88a8b3;
margin-top: 4px;
}
.ps-03__fc {
text-align: left !important;
color: #88a8b3 !important;
font-weight: 500 !important;
background: transparent !important;
}
.ps-03__tbl tbody th {
text-align: left;
font-weight: 500;
color: #cfeaf2;
}
.ps-03__rec {
background: rgba(34,211,238,0.06);
color: #22d3ee;
position: relative;
}
.ps-03__tbl thead th.ps-03__rec {
background: linear-gradient(180deg, rgba(34,211,238,0.18), rgba(34,211,238,0.04));
color: #5eead4;
}
.ps-03__pill {
position: absolute;
top: -10px;
left: 50%;
transform: translateX(-50%);
background: #22d3ee;
color: #06141a;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 3px 10px;
border-radius: 999px;
}
.ps-03__yes {
display: inline-block;
width: 22px;
height: 22px;
line-height: 22px;
border-radius: 50%;
background: rgba(34,211,238,0.15);
color: #22d3ee;
font-weight: 700;
}
.ps-03__no {
color: #4a606a;
font-weight: 500;
}
.ps-03__tbl tfoot td {
padding-top: 18px;
padding-bottom: 4px;
border: 0;
}
.ps-03__cta {
display: inline-block;
padding: 9px 16px;
border-radius: 7px;
font-size: 12.5px;
font-weight: 600;
text-decoration: none;
border: 1px solid rgba(34,211,238,0.3);
color: #5eead4;
transition: background 0.18s, color 0.18s;
}
.ps-03__cta:hover {
background: rgba(34,211,238,0.18);
color: #f1fbff;
}
.ps-03__cta-pri {
background: #22d3ee;
color: #06141a;
border-color: #22d3ee;
}
.ps-03__cta-pri:hover {
background: #5eead4;
color: #06141a;
}
.ps-03__cta:focus-visible {
outline: 2px solid #22d3ee;
outline-offset: 3px;
}
@media (max-width: 720px) {
.ps-03__scroll {
padding-bottom: 8px;
}
.ps-03__tbl thead th,
.ps-03__tbl tbody th,
.ps-03__tbl td {
padding: 10px 8px;
font-size: 12px;
}
.ps-03__pill {
font-size: 9px;
padding: 2px 6px;
}
}.ps-03 {
padding: clamp(28px, 5vw, 56px) clamp(16px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #06141a;
color: #e0f2f7;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-03__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 36px);
}
.ps-03__head h2 {
font-size: clamp(22px, 3.2vw, 32px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0 0 8px;
color: #f1fbff;
}
.ps-03__head p {
color: #88a8b3;
margin: 0;
font-size: 14px;
}
.ps-03__scroll {
overflow-x: auto;
overflow-y: visible;
-webkit-overflow-scrolling: touch;
max-width: 980px;
margin: 0 auto;
padding-top: 14px;
}
.ps-03__tbl {
width: 100%;
border-collapse: separate;
border-spacing: 0;
font-size: 13.5px;
min-width: 720px;
}
.ps-03__tbl th,
.ps-03__tbl td {
text-align: center;
padding: 14px 12px;
border-bottom: 1px solid rgba(34,211,238,0.1);
}
.ps-03__tbl thead th {
font-size: 14px;
font-weight: 700;
color: #cfeaf2;
background: #0c1f27;
position: relative;
}
.ps-03__tbl thead th span:not(.ps-03__pill) {
display: block;
font-size: 13px;
font-weight: 500;
color: #88a8b3;
margin-top: 4px;
}
.ps-03__fc {
text-align: left !important;
color: #88a8b3 !important;
font-weight: 500 !important;
background: transparent !important;
}
.ps-03__tbl tbody th {
text-align: left;
font-weight: 500;
color: #cfeaf2;
}
.ps-03__rec {
background: rgba(34,211,238,0.06);
color: #22d3ee;
position: relative;
}
.ps-03__tbl thead th.ps-03__rec {
background: linear-gradient(180deg, rgba(34,211,238,0.18), rgba(34,211,238,0.04));
color: #5eead4;
}
.ps-03__pill {
position: absolute;
top: -10px;
left: 50%;
transform: translateX(-50%);
background: #22d3ee;
color: #06141a;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 3px 10px;
border-radius: 999px;
}
.ps-03__yes {
display: inline-block;
width: 22px;
height: 22px;
line-height: 22px;
border-radius: 50%;
background: rgba(34,211,238,0.15);
color: #22d3ee;
font-weight: 700;
}
.ps-03__no {
color: #4a606a;
font-weight: 500;
}
.ps-03__tbl tfoot td {
padding-top: 18px;
padding-bottom: 4px;
border: 0;
}
.ps-03__cta {
display: inline-block;
padding: 9px 16px;
border-radius: 7px;
font-size: 12.5px;
font-weight: 600;
text-decoration: none;
border: 1px solid rgba(34,211,238,0.3);
color: #5eead4;
transition: background 0.18s, color 0.18s;
}
.ps-03__cta:hover {
background: rgba(34,211,238,0.18);
color: #f1fbff;
}
.ps-03__cta-pri {
background: #22d3ee;
color: #06141a;
border-color: #22d3ee;
}
.ps-03__cta-pri:hover {
background: #5eead4;
color: #06141a;
}
.ps-03__cta:focus-visible {
outline: 2px solid #22d3ee;
outline-offset: 3px;
}
@media (max-width: 720px) {
.ps-03__scroll {
padding-bottom: 8px;
}
.ps-03__tbl thead th,
.ps-03__tbl tbody th,
.ps-03__tbl td {
padding: 10px 8px;
font-size: 12px;
}
.ps-03__pill {
font-size: 9px;
padding: 2px 6px;
}
}Here's a working CSS Pricing Section from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Feature Comparison Table
Source: https://codefronts.com/layouts/css-pricing-sections/feature-comparison-table/
A real <table> with proper <th scope>, sticky header row, and check / dash cells comparing four plans across nine features. Cyan accent on the recommended column. Mobile fallback collapses to a stacked card list under 720px.
## HTML
```html
<section class="ps-03" aria-label="Plan comparison">
<header class="ps-03__head">
<h2>Compare every feature.</h2>
<p>Pick the column that matches what you ship today.</p>
</header>
<div class="ps-03__scroll">
<table class="ps-03__tbl">
<thead>
<tr>
<th scope="col" class="ps-03__fc">Feature</th>
<th scope="col">Free<br /><span>$0</span></th>
<th scope="col" class="ps-03__rec">
<span class="ps-03__pill">Recommended</span>Pro<br /><span>$24</span>
</th>
<th scope="col">Team<br /><span>$48</span></th>
<th scope="col">Enterprise<br /><span>Contact</span></th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Projects</th>
<td>1</td>
<td class="ps-03__rec">10</td>
<td>50</td>
<td>Unlimited</td>
</tr>
<tr>
<th scope="row">Storage</th>
<td>500 MB</td>
<td class="ps-03__rec">10 GB</td>
<td>50 GB</td>
<td>500 GB</td>
</tr>
<tr>
<th scope="row">Custom domain</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Team roles</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Priority support</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">SSO & SAML</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Audit logs</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">99.99% SLA</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Dedicated CSM</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row" class="ps-03__fc"></th>
<td><a class="ps-03__cta" href="#free">Get started</a></td>
<td class="ps-03__rec">
<a class="ps-03__cta ps-03__cta-pri" href="#pro">Choose Pro →</a>
</td>
<td><a class="ps-03__cta" href="#team">Choose Team</a></td>
<td><a class="ps-03__cta" href="#ent">Talk to sales</a></td>
</tr>
</tfoot>
</table>
</div>
</section>
```
## CSS
```css
.ps-03 {
padding: clamp(28px, 5vw, 56px) clamp(16px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #06141a;
color: #e0f2f7;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-03__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 36px);
}
.ps-03__head h2 {
font-size: clamp(22px, 3.2vw, 32px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0 0 8px;
color: #f1fbff;
}
.ps-03__head p {
color: #88a8b3;
margin: 0;
font-size: 14px;
}
.ps-03__scroll {
overflow-x: auto;
overflow-y: visible;
-webkit-overflow-scrolling: touch;
max-width: 980px;
margin: 0 auto;
padding-top: 14px;
}
.ps-03__tbl {
width: 100%;
border-collapse: separate;
border-spacing: 0;
font-size: 13.5px;
min-width: 720px;
}
.ps-03__tbl th,
.ps-03__tbl td {
text-align: center;
padding: 14px 12px;
border-bottom: 1px solid rgba(34,211,238,0.1);
}
.ps-03__tbl thead th {
font-size: 14px;
font-weight: 700;
color: #cfeaf2;
background: #0c1f27;
position: relative;
}
.ps-03__tbl thead th span:not(.ps-03__pill) {
display: block;
font-size: 13px;
font-weight: 500;
color: #88a8b3;
margin-top: 4px;
}
.ps-03__fc {
text-align: left !important;
color: #88a8b3 !important;
font-weight: 500 !important;
background: transparent !important;
}
.ps-03__tbl tbody th {
text-align: left;
font-weight: 500;
color: #cfeaf2;
}
.ps-03__rec {
background: rgba(34,211,238,0.06);
color: #22d3ee;
position: relative;
}
.ps-03__tbl thead th.ps-03__rec {
background: linear-gradient(180deg, rgba(34,211,238,0.18), rgba(34,211,238,0.04));
color: #5eead4;
}
.ps-03__pill {
position: absolute;
top: -10px;
left: 50%;
transform: translateX(-50%);
background: #22d3ee;
color: #06141a;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 3px 10px;
border-radius: 999px;
}
.ps-03__yes {
display: inline-block;
width: 22px;
height: 22px;
line-height: 22px;
border-radius: 50%;
background: rgba(34,211,238,0.15);
color: #22d3ee;
font-weight: 700;
}
.ps-03__no {
color: #4a606a;
font-weight: 500;
}
.ps-03__tbl tfoot td {
padding-top: 18px;
padding-bottom: 4px;
border: 0;
}
.ps-03__cta {
display: inline-block;
padding: 9px 16px;
border-radius: 7px;
font-size: 12.5px;
font-weight: 600;
text-decoration: none;
border: 1px solid rgba(34,211,238,0.3);
color: #5eead4;
transition: background 0.18s, color 0.18s;
}
.ps-03__cta:hover {
background: rgba(34,211,238,0.18);
color: #f1fbff;
}
.ps-03__cta-pri {
background: #22d3ee;
color: #06141a;
border-color: #22d3ee;
}
.ps-03__cta-pri:hover {
background: #5eead4;
color: #06141a;
}
.ps-03__cta:focus-visible {
outline: 2px solid #22d3ee;
outline-offset: 3px;
}
@media (max-width: 720px) {
.ps-03__scroll {
padding-bottom: 8px;
}
.ps-03__tbl thead th,
.ps-03__tbl tbody th,
.ps-03__tbl td {
padding: 10px 8px;
font-size: 12px;
}
.ps-03__pill {
font-size: 9px;
padding: 2px 6px;
}
}
```Here's a working CSS Pricing Section from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Feature Comparison Table
Source: https://codefronts.com/layouts/css-pricing-sections/feature-comparison-table/
A real <table> with proper <th scope>, sticky header row, and check / dash cells comparing four plans across nine features. Cyan accent on the recommended column. Mobile fallback collapses to a stacked card list under 720px.
## HTML
```html
<section class="ps-03" aria-label="Plan comparison">
<header class="ps-03__head">
<h2>Compare every feature.</h2>
<p>Pick the column that matches what you ship today.</p>
</header>
<div class="ps-03__scroll">
<table class="ps-03__tbl">
<thead>
<tr>
<th scope="col" class="ps-03__fc">Feature</th>
<th scope="col">Free<br /><span>$0</span></th>
<th scope="col" class="ps-03__rec">
<span class="ps-03__pill">Recommended</span>Pro<br /><span>$24</span>
</th>
<th scope="col">Team<br /><span>$48</span></th>
<th scope="col">Enterprise<br /><span>Contact</span></th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Projects</th>
<td>1</td>
<td class="ps-03__rec">10</td>
<td>50</td>
<td>Unlimited</td>
</tr>
<tr>
<th scope="row">Storage</th>
<td>500 MB</td>
<td class="ps-03__rec">10 GB</td>
<td>50 GB</td>
<td>500 GB</td>
</tr>
<tr>
<th scope="row">Custom domain</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Team roles</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Priority support</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">SSO & SAML</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Audit logs</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">99.99% SLA</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
<tr>
<th scope="row">Dedicated CSM</th>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td class="ps-03__rec"><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__no" aria-label="not included">—</span></td>
<td><span class="ps-03__yes" aria-label="included">✓</span></td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row" class="ps-03__fc"></th>
<td><a class="ps-03__cta" href="#free">Get started</a></td>
<td class="ps-03__rec">
<a class="ps-03__cta ps-03__cta-pri" href="#pro">Choose Pro →</a>
</td>
<td><a class="ps-03__cta" href="#team">Choose Team</a></td>
<td><a class="ps-03__cta" href="#ent">Talk to sales</a></td>
</tr>
</tfoot>
</table>
</div>
</section>
```
## CSS
```css
.ps-03 {
padding: clamp(28px, 5vw, 56px) clamp(16px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #06141a;
color: #e0f2f7;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-03__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 36px);
}
.ps-03__head h2 {
font-size: clamp(22px, 3.2vw, 32px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0 0 8px;
color: #f1fbff;
}
.ps-03__head p {
color: #88a8b3;
margin: 0;
font-size: 14px;
}
.ps-03__scroll {
overflow-x: auto;
overflow-y: visible;
-webkit-overflow-scrolling: touch;
max-width: 980px;
margin: 0 auto;
padding-top: 14px;
}
.ps-03__tbl {
width: 100%;
border-collapse: separate;
border-spacing: 0;
font-size: 13.5px;
min-width: 720px;
}
.ps-03__tbl th,
.ps-03__tbl td {
text-align: center;
padding: 14px 12px;
border-bottom: 1px solid rgba(34,211,238,0.1);
}
.ps-03__tbl thead th {
font-size: 14px;
font-weight: 700;
color: #cfeaf2;
background: #0c1f27;
position: relative;
}
.ps-03__tbl thead th span:not(.ps-03__pill) {
display: block;
font-size: 13px;
font-weight: 500;
color: #88a8b3;
margin-top: 4px;
}
.ps-03__fc {
text-align: left !important;
color: #88a8b3 !important;
font-weight: 500 !important;
background: transparent !important;
}
.ps-03__tbl tbody th {
text-align: left;
font-weight: 500;
color: #cfeaf2;
}
.ps-03__rec {
background: rgba(34,211,238,0.06);
color: #22d3ee;
position: relative;
}
.ps-03__tbl thead th.ps-03__rec {
background: linear-gradient(180deg, rgba(34,211,238,0.18), rgba(34,211,238,0.04));
color: #5eead4;
}
.ps-03__pill {
position: absolute;
top: -10px;
left: 50%;
transform: translateX(-50%);
background: #22d3ee;
color: #06141a;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 3px 10px;
border-radius: 999px;
}
.ps-03__yes {
display: inline-block;
width: 22px;
height: 22px;
line-height: 22px;
border-radius: 50%;
background: rgba(34,211,238,0.15);
color: #22d3ee;
font-weight: 700;
}
.ps-03__no {
color: #4a606a;
font-weight: 500;
}
.ps-03__tbl tfoot td {
padding-top: 18px;
padding-bottom: 4px;
border: 0;
}
.ps-03__cta {
display: inline-block;
padding: 9px 16px;
border-radius: 7px;
font-size: 12.5px;
font-weight: 600;
text-decoration: none;
border: 1px solid rgba(34,211,238,0.3);
color: #5eead4;
transition: background 0.18s, color 0.18s;
}
.ps-03__cta:hover {
background: rgba(34,211,238,0.18);
color: #f1fbff;
}
.ps-03__cta-pri {
background: #22d3ee;
color: #06141a;
border-color: #22d3ee;
}
.ps-03__cta-pri:hover {
background: #5eead4;
color: #06141a;
}
.ps-03__cta:focus-visible {
outline: 2px solid #22d3ee;
outline-offset: 3px;
}
@media (max-width: 720px) {
.ps-03__scroll {
padding-bottom: 8px;
}
.ps-03__tbl thead th,
.ps-03__tbl tbody th,
.ps-03__tbl td {
padding: 10px 8px;
font-size: 12px;
}
.ps-03__pill {
font-size: 9px;
padding: 2px 6px;
}
}
```How this works
The comparison table is a real semantic <table> with proper <th scope="col"> on the header row and <th scope="row"> on each feature — the pattern the WCAG 1.3.1 spec requires for screen-reader row/column association, and one of the biggest SEO trust signals for an enterprise price comparison table page. The .ps-03__scroll wrapper uses overflow-x: auto; -webkit-overflow-scrolling: touch with min-width: 720px on the table itself, so on narrow viewports the table gains a horizontal scroll gesture instead of collapsing — the pattern Stripe, Datadog, and Linear all ship on their b2b pricing section. border-collapse: separate; border-spacing: 0 is the load-bearing choice: you cannot apply border-radius to individual cells with border-collapse: collapse, and the recommended column's rounded gradient header depends on it.
The palette is a deep aqua base #06141a with body text #e0f2f7 and cyan accent #22d3ee (Tailwind cyan-400) reserved for the recommended Pro column and every included-check-mark. The recommended column gets background: rgba(34,211,238,0.06) throughout the whole vertical strip — a persistent visual guide-rail down the table so the eye never loses which tier it's evaluating on row six or seven. The header background: linear-gradient(180deg, rgba(34,211,238,0.18), rgba(34,211,238,0.04)) is a top-heavy fade that mimics a spotlight without adding a paint-cost shadow. Inter at 13.5px body, 14px headers, and the mono-style price span subline give the dense-data authority the enterprise SaaS pricing tier design demands.
Why it converts: forced feature comparison is Iyengar's structured-choice pattern — the more feature rows you show, the more the visitor discovers what they'd give up by picking the cheaper tier, and the more they anchor upward. Baymard research on enterprise pricing pages shows structured comparison tables reduce choice paralysis by ~60% versus tile-only tier layouts because the visitor stops asking "what am I missing?" once every gap is visible. The Recommended pill above the Pro column is Cialdini social proof that survives even when the user scrolls past the header — the persistent cyan tint keeps that endorsement alive on every row.
Make it yours
- Recolor cyan to your brand: swap
#22d3eeand#5eead4(the darker recommended-header accent) plus everyrgba(34,211,238, ...)to your accent's RGB. Keep the recommended-column background at ~0.06 alpha — higher than 0.10 and the tint starts to bleed into perceived-lower-contrast for the row headers under it. - Swap Inter for
'IBM Plex Sans'for enterprise / gov,'JetBrains Mono'for the pricespanto lean into a developer-tools pricing tier design, or'Söhne'for premium B2B SaaS. Keep thefont-size: 13pxsecondary weight on the price sublines — smaller than 12px fails WCAG 1.4.4 resize at 200% on Chrome mobile. - Change the check-mark cell style: the current
.ps-03__yesis a filled cyan pill with a bold checkmark. For a minimal table, drop the pill background and use just the check glyph in accent color. For an enterprise / compliance look, swap ✓ to an SVG shield icon and use the same masked-fill trick from demo 01. - For light-mode inversion: swap
#06141a→#f0fafc,#e0f2f7→#06141a, keep#22d3eeas accent but drop to#0891b2(cyan-600) for the recommended header text — the lighter cyan disappears on cream. - Tailwind mapping: section
bg-[#06141a] text-cyan-50, scrolloverflow-x-auto -webkit-overflow-scrolling-touch max-w-[980px] mx-auto, tablew-full border-separate border-spacing-0 text-[13.5px] min-w-[720px], recommended cellbg-cyan-400/[0.06] text-cyan-400, pillabsolute -top-2.5 left-1/2 -translate-x-1/2 bg-cyan-400 text-[#06141a] text-[10px] font-bold uppercase tracking-[0.08em] px-2.5 py-0.5 rounded-full.
Gotchas — read before shipping
- The
overflow-x: autoscroll container is required on any pricing tier comparison table under 720px, but if you nest this table inside a parent withoverflow: hidden, the scroll gesture is captured by the parent and users can't reach the Enterprise column on mobile. Audit the parent chain up tobodybefore shipping. - The
.ps-03__pillusesposition: absolute; top: -10pxon the recommended<th>— but<th>requiresposition: relativeto become a containing block, and browsers vary on whether table cells accept it. Chrome 108+ and Safari 15.4+ handle it; older Firefox needs a spec-compliantdisplay: blockfallback wrapper if you support ESR. - Do NOT use
display: blockon the table cells to force a mobile layout — that strips the table's implicit ARIA table role and screen readers announce it as a list, killing the WCAG 1.3.1 comparison semantics. Use the horizontal-scroll fallback instead, or duplicate the data as stacked<dl>pairs and hide the table withdisplay: noneat the breakpoint. - The
.ps-03__noem-dash (—) hascolor: #4a606awhich measures ~3.4:1 against#06141a— passing WCAG 1.4.11 non-text contrast for informational graphics (3:1 minimum) but failing 1.4.3 text contrast (4.5:1). Because the dash conveys "not included," pair it with thearia-label="not included"already in the source; that keeps the visual gray but reaches WCAG parity via alt-text. - In React, do not conditionally render entire feature rows based on a
show moretoggle — every row toggle forces the table to re-layout the min-width calculation, triggering a CLS event that Core Web Vitals counts against the pricing page. If you must collapse rows, animateopacity+visibility: hiddenand keep the row in the DOM. - The
.ps-03__fcrule uses!importantfour times to override the header-row defaults on the first (feature-label) column. This is a legit use — you're resetting inherited table-header styles on a semantic corner-cell. Do not remove the !importants unless you rewrite as a sibling selector, or the corner cell picks up the centered cyan header treatment and the whole first column shifts right.