Why semantic HTML matters
An <article> tells browsers and screen readers that this block is a complete, standalone unit — not just a generic <div>.
That structure powers reader modes, search snippets, and assistive tech with no extra work.
The small text-and-status pieces that fill a page — definition lists, callouts, alerts, notifications, badges, tags, and labels. Each with a live demo and the HTML & CSS.
A <dl> holds term/description pairs — perfect for glossaries, metadata, or FAQs. <dt> is the term, <dd> is its description.
HTML
<dl> <dt>HTML</dt> <dd>The structure and content of a page.</dd> <dt>CSS</dt> <dd>The presentation — colors, layout, type.</dd> </dl>
CSS
dt { font-weight: 700; }
dd { margin: 0 0 12px; color: #6b7280; }
A callout pulls a note, tip, or warning out of the flow with a colored bar and an icon, so it catches the eye without shouting.
HTML
<aside class="callout">
<i class="icon"></i>
<div>
<p class="title">Tip</p>
<p>Keep callouts short — one idea each.</p>
</div>
</aside>
CSS
.callout {
display: flex; gap: 12px;
border-left: 4px solid #38bdf8; /* accent bar */
background: #eef6fd;
border-radius: 8px;
padding: 14px 16px;
}
Alerts confirm success, flag errors, or warn. Pair color with an icon and text so meaning never depends on color alone, and use role="alert" for important ones.
HTML
<div class="alert success" role="alert"> <i class="icon-check"></i> Your changes were saved. <button class="close" aria-label="Dismiss">×</button> </div> <div class="alert error" role="alert"> <i class="icon-x"></i> Something went wrong. <button class="close" aria-label="Dismiss">×</button> </div> <div class="alert warn"> <i class="icon-warning"></i> Your session expires in 5 minutes. <button class="close" aria-label="Dismiss">×</button> </div>
CSS
.alert { display: flex; gap: 10px; align-items: center;
padding: 12px 14px; border-radius: 8px; font-weight: 600;
margin-bottom: 10px; }
.alert.success { background: #dcfce7; color: #166534; }
.alert.error { background: #fee2e2; color: #991b1b; }
.alert.warn { background: #fef9c3; color: #854d0e; }
.alert .close { margin-left: auto; background: none; border: none;
color: inherit; cursor: pointer; font-size: 1rem; }
JavaScript
// Dismiss an alert when its close button is clicked
document.querySelectorAll('.alert .close').forEach(function (btn) {
btn.addEventListener('click', function () {
btn.closest('.alert').remove();
});
});
role="alert" only for messages that should interrupt and be announced.A notification (toast) is a small floating card confirming an action, usually with a title, message, and a close button. In a real app it appears in a corner and fades after a few seconds.
“Header Patterns” was added.
HTML
<div class="toast" role="status">
<i class="icon"></i>
<div>
<p class="title">Saved to your library</p>
<p>"Header Patterns" was added.</p>
</div>
<button class="close" aria-label="Dismiss">×</button>
</div>
CSS
.toast {
display: flex; gap: 12px; align-items: flex-start;
background: #fff; border: 1px solid #e5e7eb;
border-radius: 10px; padding: 14px 16px;
box-shadow: 0 8px 24px rgba(0,0,0,.1);
max-width: 360px;
transition: opacity .25s ease, transform .25s ease;
}
.toast.dismissing { opacity: 0; transform: translateY(-6px); }
.toast .close { margin-left: auto; background: none; border: none;
color: #9ca3af; cursor: pointer; font-size: 1rem; }
/* In production, position: fixed; bottom: 24px; right: 24px; */
JavaScript
// Dismiss the toast: fade out, then remove from the DOM
document.querySelectorAll('.toast .close').forEach(function (btn) {
btn.addEventListener('click', function () {
var toast = btn.closest('.toast');
toast.classList.add('dismissing');
setTimeout(function () { toast.remove(); }, 250);
});
});
Badges show a count (unread messages) or a quick status (“New”). Position a count over an icon with relative/absolute positioning.
HTML
<span class="bell"> <i class="icon-bell"></i> <span class="badge">3</span> </span>
CSS
.bell { position: relative; display: inline-flex; }
.badge {
position: absolute; top: -4px; right: -7px;
min-width: 20px; height: 20px; padding: 0 6px;
border-radius: 999px;
background: #ef4444; color: #fff;
font-size: .7rem; font-weight: 700;
display: inline-flex; align-items: center; justify-content: center;
}
Tags (chips) label content by topic and are often removable. A pill shape with a small close button is the usual look.
HTML
<span class="tag"> HTML <button aria-label="Remove HTML tag">×</button> </span>
CSS
.tag {
display: inline-flex; align-items: center; gap: 6px;
background: #e0f2fe; color: #0369a1;
border-radius: 999px; /* pill shape */
padding: 5px 12px;
font-size: .8rem; font-weight: 600;
}
.tag button { background: none; border: none; cursor: pointer; }
A status label is a small colored block of text — “Draft,” “Live,” “Archived.” Like alerts, keep the word visible so color isn't the only signal.
HTML
<span class="label draft">Draft</span> <span class="label live">Live</span> <span class="label archived">Archived</span>
CSS
.label {
display: inline-block;
border-radius: 6px; padding: 3px 10px;
font-size: .72rem; font-weight: 700;
text-transform: uppercase; letter-spacing: .04em;
}
.label.draft { background: #e5e7eb; color: #374151; }
.label.live { background: #dcfce7; color: #166534; }
.label.archived { background: #fee2e2; color: #991b1b; }
Headings (<h1>–<h6>) give a page structure and rank. A display face like Poppins from Google Fonts makes them stand out from the body text.
HTML — load the font, then use it
<!-- in <head> --> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@600;700&display=swap" rel="stylesheet"> <h1>Page title</h1> <h2>Section heading</h2> <h3>Sub-heading</h3>
CSS
h1, h2, h3 { font-family: 'Poppins', sans-serif; }
h1 { font-size: 2rem; line-height: 1.15; font-weight: 700; }
h2 { font-size: 1.4rem; font-weight: 600; }
h3 { font-size: 1.1rem; font-weight: 600; }
<link> into your <head>, then set font-family.Body copy wants a comfortable line-height and a measure of ~50–75 characters. A humanist sans like Inter from Google Fonts reads cleanly at small sizes.
Good paragraphs are easy on the eyes: enough line-height to separate lines, and a width that keeps the eye from getting lost on the way back to the start.
Capping the measure around 65 characters does most of the work — longer lines are surprisingly tiring to read.
HTML
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet"> <p>Good paragraphs are easy on the eyes…</p>
CSS
p {
font-family: 'Inter', sans-serif;
font-size: 1rem;
line-height: 1.7; /* breathing room between lines */
max-width: 65ch; /* ~65 characters per line */
}
A pull quote lifts a striking sentence from the article and sets it large. An elegant serif like Playfair Display from Google Fonts gives it editorial flair.
“Good design is invisible — you only notice it when it's missing.”
HTML
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital@1&display=swap" rel="stylesheet"> <p class="pull-quote">“Good design is invisible…”</p>
CSS
.pull-quote {
font-family: 'Playfair Display', Georgia, serif;
font-style: italic;
font-size: 1.7rem;
line-height: 1.35;
max-width: 28ch;
text-align: center;
}
A <blockquote> sets off quoted text — indented, with an accent border and an attribution in <cite>. Body text here uses Inter.
Content is the reason people visit a site — everything else is in service of it.
— Our content style guide
HTML
<blockquote> <p>Content is the reason people visit a site…</p> <cite>— Our content style guide</cite> </blockquote>
CSS
blockquote {
font-family: 'Inter', sans-serif;
border-left: 4px solid #38bdf8; /* accent bar */
background: #f8fafc;
padding: 14px 18px;
}
blockquote cite { display: block; margin-top: 8px; font-style: normal; color: #6b7280; }
Use a <ul> when order doesn't matter (bulleted) and an <ol> when it does (numbered, like steps). The browser handles the markers; CSS can restyle them.
HTML
<ul> <!-- unordered: bullets --> <li>Apples</li> <li>Oranges</li> </ul> <ol> <!-- ordered: numbers --> <li>Preheat the oven</li> <li>Mix the batter</li> </ol>
CSS
ul { list-style: disc; } /* • bullets */
ol { list-style: decimal; } /* 1. 2. 3. numbers */
li { margin: 4px 0; } /* space out items */
ul, ol { padding-left: 22px; }/* room for the markers */
A <figure> wraps an image (or chart, code, video) together with its <figcaption>, so the two are linked semantically rather than just sitting near each other.
HTML
<figure> <img src="chart.png" alt="Quarterly sales chart"> <figcaption>Figure 1. Quarterly sales, 2026.</figcaption> </figure>
CSS
figure { margin: 0; max-width: 360px; }
figure img { width: 100%; border-radius: 10px; }
figcaption { font-size: .85rem; color: #6b7280; margin-top: 8px; text-align: center; }
The <figcaption> is the caption itself — a short description or photo credit tied to the figure. Keep it small, muted, and just below the media.
HTML
<figure> <img src="bay.jpg" alt="Sunrise over the bay"> <figcaption><b>Sunrise over the bay.</b> Photo: J. Parker.</figcaption> </figure>
CSS
figcaption {
font-size: .8rem;
color: #6b7280; /* muted, secondary to the image */
margin-top: 6px;
}
figcaption b { color: #374151; } /* lead phrase stands out */
An <article> wraps content that stands on its own — a blog post, news story, or comment — so it makes sense if syndicated or read in isolation. It usually opens with a heading.
An <article> tells browsers and screen readers that this block is a complete, standalone unit — not just a generic <div>.
That structure powers reader modes, search snippets, and assistive tech with no extra work.
HTML
<article> <h2>Why semantic HTML matters</h2> <p class="byline">By Dr. G · May 2026</p> <p>An <article> is a complete, standalone unit…</p> </article>
CSS
article { max-width: 65ch; } /* readable measure */
article h2 { margin-bottom: 4px; }
article .byline { color: #9aa3b2; font-size: .8rem; margin-bottom: 10px; }
article p + p { margin-top: 10px; } /* space paragraphs */
A testimonial pairs a short quote with the person's name, role, and (often) a rating and avatar. Keep the quote brief and the attribution clear so it reads as credible.
“The live demos made everything click — I shipped my first site the same week.”
HTML
<figure class="testimonial">
<div class="stars" aria-label="5 out of 5">★★★★★</div>
<blockquote>“The live demos made everything click.”</blockquote>
<figcaption class="who">
<img class="avatar" src="jamie.jpg" alt="">
<div><b>Jamie L.</b><span>Front-end student</span></div>
</figcaption>
</figure>
CSS
.testimonial { border: 1px solid #e5e7eb; border-radius: 12px; padding: 18px; }
.testimonial .stars { color: #f59e0b; }
.testimonial .who { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.testimonial .avatar { width: 40px; height: 40px; border-radius: 50%; }
The native <details> / <summary> elements give you an accordion FAQ with zero JavaScript — click a question to expand it. Try it below.
No — start with the Get Started pages and follow along. You'll pick up HTML and CSS as you go.
Yes. Every page, demo, and code snippet is free to use and learn from.
Absolutely — copy any HTML/CSS and adapt it to your own work.
HTML
<details> <summary>Do I need to know how to code?</summary> <p>No — start with the Get Started pages.</p> </details> <details> <summary>Is the Playground free?</summary> <p>Yes, completely.</p> </details>
CSS
summary { cursor: pointer; list-style: none; } /* hide default arrow */
summary::after { content: "+"; float: right; } /* custom marker */
details[open] summary::after { content: "\2212"; } /* minus when open */
JavaScript (optional accordion behavior)
// Single-open accordion: opening one closes the others.
// Native <details> already toggles on its own without JS.
document.querySelectorAll('.cp-faq details').forEach(function (d) {
d.addEventListener('toggle', function () {
if (!d.open) return;
document.querySelectorAll('.cp-faq details').forEach(function (other) {
if (other !== d) other.open = false;
});
});
});
<details> is built into the browser — accessible, keyboard-friendly, and open/closes with no script. The JavaScript above just adds single-open accordion behavior.More text components in Text Lab and Semantic HTML; toasts and modals in Microinteractions — or browse the full Component Library.