CSS Tutorial
CSS Project: Pricing Table
Three pricing cards in a row. The featured plan is slightly larger and uses a stronger border.
What you will build
Three workshop passes for Harbor studio: Weekday, Harbor, and Season. They sit in a row on a wide window. The Harbor plan is the featured card — a thicker sky border and a slight scale so it reads as the recommended choice without a second layout.
Each card lists a name, a price, three perks, and a button. Flex (or grid) keeps equal height. The featured card is still one of three siblings, not a separate page region.
Open an example with Try it in CSS. That loads /css/try — a live page preview.
Properties you will use
| Property | Job on this page |
|---|---|
display: flex | Puts the three cards in a wrapping row |
flex on each card | Shares width so the row stays even |
transform: scale | Makes the featured plan a little larger |
border | Quiet on the side cards, strong on Harbor |
align-items: stretch | Keeps card bottoms lined up |
Scale is visual emphasis. Do not scale so far that the middle card covers its neighbors. A few percent is enough.
Build in slices
Start with one card. Price is large. Perks are a list. The button is already a control, not a styled span.
Example
<style>
body { font-family: system-ui, sans-serif; background: #e0f2fe; color: #0c4a6e; margin: 1.5rem; }
.plan {
background: #fff;
border: 1px solid #7dd3fc;
border-radius: 1rem;
padding: 1.3rem 1.25rem 1.4rem;
max-width: 16rem;
}
.price { font-size: 2rem; font-weight: 800; margin: 0.2rem 0 0.8rem; }
ul { margin: 0 0 1rem; padding-left: 1.1rem; }
button {
width: 100%;
font: inherit;
font-weight: 700;
border: 0;
border-radius: 0.5rem;
padding: 0.6rem;
background: #0284c7;
color: #fff;
}
</style>
<article class="plan">
<h2>Weekday</h2>
<p class="price">€48</p>
<ul>
<li>Four morning sessions</li>
<li>Press access</li>
<li>Cafe discount</li>
</ul>
<button type="button">Choose Weekday</button>
</article>Then put three cards in a flex row and mark the middle one featured. Scale and a thicker border do the emphasis. A wrap on narrow viewports stacks them.
Example
<style>
.plans {
display: flex;
flex-wrap: wrap;
gap: 1rem;
align-items: stretch;
justify-content: center;
}
.plan { flex: 1 1 14rem; }
.featured {
border: 3px solid #0284c7;
transform: scale(1.04);
box-shadow: 0 16px 28px rgba(12, 74, 110, 0.16);
}
</style>
<div class="plans">
<article class="plan">
<h2>Weekday</h2>
<p class="price">€48</p>
</article>
<article class="plan featured">
<h2>Harbor</h2>
<p class="price">€86</p>
</article>
<article class="plan">
<h2>Season</h2>
<p class="price">€210</p>
</article>
</div>Names and prices are enough to test the row. The complete document below adds perks and buttons. Preview at /css/try.
Complete page
Three real plans, one featured. Buttons keep a focus ring. The row wraps below about 40 rem so a phone stacks the cards without clipping the scaled middle plan.
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Harbor studio — workshop passes</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
background: #e0f2fe;
color: #0c4a6e;
font-family: system-ui, sans-serif;
padding: 2rem 1.25rem;
}
h1 { text-align: center; margin: 0 0 0.35rem; }
.lead { text-align: center; color: #075985; margin: 0 0 1.6rem; }
.plans {
display: flex;
flex-wrap: wrap;
gap: 1.1rem;
align-items: stretch;
justify-content: center;
max-width: 58rem;
margin: 0 auto;
}
.plan {
flex: 1 1 15rem;
background: #fff;
border: 1px solid #7dd3fc;
border-radius: 1rem;
padding: 1.35rem 1.25rem 1.4rem;
display: flex;
flex-direction: column;
}
.plan h2 { margin: 0; font-size: 1.15rem; }
.price { font-size: 2.1rem; font-weight: 800; margin: 0.35rem 0 0.85rem; }
ul {
margin: 0 0 1.1rem;
padding-left: 1.15rem;
color: #075985;
flex: 1;
}
button {
font: inherit;
font-weight: 700;
width: 100%;
border: 0;
border-radius: 0.5rem;
padding: 0.65rem;
background: #0284c7;
color: #fff;
cursor: pointer;
}
button:hover { background: #0369a1; }
button:focus-visible { outline: 3px solid #38bdf8; outline-offset: 3px; }
.featured {
border: 3px solid #0284c7;
transform: scale(1.04);
box-shadow: 0 16px 28px rgba(12, 74, 110, 0.16);
}
.featured button { background: #0c4a6e; }
.featured button:hover { background: #082f49; }
@media (max-width: 40rem) {
.featured { transform: none; }
}
</style>
</head>
<body>
<h1>Workshop passes</h1>
<p class="lead">Print days at Harbor studio. Cafe next door included on Harbor and Season.</p>
<div class="plans">
<article class="plan">
<h2>Weekday</h2>
<p class="price">€48</p>
<ul>
<li>Four morning sessions</li>
<li>Press access until 13:00</li>
<li>10% off sourdough</li>
</ul>
<button type="button">Choose Weekday</button>
</article>
<article class="plan featured">
<h2>Harbor</h2>
<p class="price">€86</p>
<ul>
<li>Eight sessions, any day</li>
<li>Evening light table</li>
<li>Cafe tab on the house once a week</li>
</ul>
<button type="button">Choose Harbor</button>
</article>
<article class="plan">
<h2>Season</h2>
<p class="price">€210</p>
<ul>
<li>Open studio all quarter</li>
<li>Guest pass for one friend</li>
<li>Priority on print runs</li>
</ul>
<button type="button">Choose Season</button>
</article>
</div>
</body>
</html>Practice tasks
- Move the
featuredclass to Season. Confirm the thicker border and scale follow the class, not the middle slot. - Change prices and rewrite the three perks. Keep one button per card.
- Raise scale to
1.08, then decide if neighbors feel crowded. Preview at /css/try.