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

Build the section inside .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
Try it in the editor →

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.

Learn HTML & CSS Intermediate for free

20 short lessons with real code and instant checks.

See the whole course →