Foundation project
Project: a pricing section
Lesson 12 of 20 · 20 min · Module 3: Accessible, interactive HTML
Build a pricing section the way a product team would: three plans that line up on desktop and stack on phones, a featured plan with a badge, and keyboard focus that is easy to follow. The product is Nimbus Drive, an imaginary cloud storage service.
Start this lesson →Free. No installation: you write and run the code in your browser, and it is checked automatically.
By the end, you’ll be able to…
- Plan a component’s HTML before its CSS
- Combine an auto-fit grid with positioned badges
- Make keyboard focus visible on a whole card
The idea
Combine what you learned in the first three modules: an auto-fit grid, positioning for the badge, a :focus-within highlight, and a clear structure for each plan, so the section also makes sense when a screen reader reads it from top to bottom.
<article class="plan">
<h3>Starter</h3>
<p class="price">0 €</p>
<ul>…</ul>
<a class="button" href="#starter">Start free</a>
</article>
01Structure first
Write the three articles with headings, prices, lists and links before any CSS. A screen reader user moving by headings should be able to compare the plans without seeing them.
02Layout from earlier lessons
The auto-fit grid stacks the cards on phones and places them side by side on wider screens. The badge uses the absolute-inside-relative pattern, so it stays in its card at every width.
03Focus for the whole card
:focus-within matches an element when it, or anything inside it, has focus. Outlining the whole card when its button is focused makes it obvious which plan a keyboard user is about to choose.
.plan:focus-within {
outline: 3px solid #2f6f4e;
outline-offset: 2px;
}
Your project brief
.plans:• three
article.plan cards (Starter, Plus, Studio), each with an h3, a p.price, a list of three features and an a.button;• mark Plus with the class
featured and give it <span class="badge">Most popular</span>, placed in the top-right corner with position: absolute inside a position: relative card;• lay out
.plans with repeat(auto-fit, minmax(min(100%, 260px), 1fr)) and gap: 20px: one column on a phone, three at 900px;• give the cards a white background,
border: 1px solid #d9e2cf, border-radius: 16px and padding: 24px, with border colour #2f6f4e for the featured one;• highlight a card while one of its links has keyboard focus:
.plan:focus-within { outline: 3px solid #2f6f4e; }.What the checks look for
- The section heading is kept
- There are exactly three plans
- Every plan has a name
- Every plan has a price
- Every plan has a call to action
- Each plan lists three features
- Only the featured plan has the badge
- Cards are positioning contexts
- The badge is positioned absolutely
- One column on a phone
- Three columns at 900px
- Plans are 20px apart
- The featured plan has a green border
- A card is highlighted while its link has focus
- Nothing overflows a phone screen
Take this with you
Good components start with meaningful HTML and add layout on top.
Go a little further
Add a monthly or yearly switch with two radio buttons and use :has() to show the matching prices.