Thinking in reusable chunks of HTML before you reach for React, Vue, or a page builder. You already know tags and semantics. The next step is spotting patterns that repeat across a site – a card, a site header, a call-to-action block – and marking them up consistently so you (or someone else) can copy, include, or style them without starting from scratch every time.
No framework required. Plain files and a bit of discipline go a long way.
What counts as a component?
A component here is a named, repeatable piece of UI with a stable HTML structure. The styling lives in CSS; the component is the skeleton.
Examples on a typical brochure site:
- Site header with logo and navigation
- Article or product card
- Testimonial block
- Newsletter signup form
- Page footer with links and copyright
If you draw the same box on three wireframes, it is probably a component.
Markup a component once, properly
Start with semantics, not class names. A card advertising a service might look like this:
<article class="service-card">
<header class="service-card__header">
<h2 class="service-card__title">Boiler servicing</h2>
</header>
<p class="service-card__summary">
Annual checks to keep your system safe and efficient.
</p>
<p><a class="service-card__link" href="/services/boiler-servicing/">
View details
</a></p>
</article>
Note the structure: <article> for a self-contained item, a single heading level that fits the page outline, a link that makes sense on its own. Classes describe the component (service-card) and its parts (service-card__title). That naming style (often called BEM) is optional but helps when you have dozens of components.
Write the HTML for one card in isolation. Open it in a browser with minimal CSS until the structure feels right. Then duplicate it for a listing page.
Reusing HTML without a framework
Static sites have a few honest options:
- Copy and paste – fine for two pages; painful for twenty.
- Partial files – save
header.htmlandfooter.html, include them with server-side includes, PHP, or your static site generator. - Template inheritance – Eleventy, Hugo, Jekyll, and similar let you define layouts and drop components into slots.
- WordPress template parts –
get_template_part()loads reusable chunks from your theme (covered more in the WordPress tutorial later in these tutorials).
The mechanism varies; the idea does not. Shared chrome (header, footer, nav) lives in one place. Page files only contain what is unique to that page.
A simple page template
Most inner pages share the same outer shell:
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<title>Services | Example Ltd</title>
<link rel="stylesheet" href="/assets/css/main.css">
</head>
<body>
<!-- include: site-header.html -->
<main id="main">
<h1>Our services</h1>
<!-- page-specific content -->
</main>
<!-- include: site-footer.html -->
</body>
</html>
Comments like <!-- include: ... --> are documentation for you until your build tool or server replaces them with real includes. The landmarks (<main>, header, footer) stay consistent on every page.
data-* attributes as hooks
Use data- attributes when JavaScript needs to find a component without scraping class names meant for CSS.
<nav class="site-nav" data-component="site-nav" aria-label="Primary">
<!-- links -->
</nav>
<form class="newsletter-form" data-component="newsletter-form" action="/subscribe/" method="post">
<!-- fields -->
</form>
Keep behaviour hooks separate from presentation classes where you can. If you rename a BEM class for styling, your JS should not break.
Document your components lightly
You do not need a full design system site on day one. A markdown file or a single components.html reference page listing each component with a short note works:
- Name of the component
- When to use it
- Required child elements (e.g. Card must have a heading)
- Example HTML snippet
Future you will forget whether the testimonial used a <figure> or a plain <blockquote>. Write it down once.
What this is not
This is not Web Components or Shadow DOM (those belong in the advanced tutorials). It is not about JavaScript frameworks. It is the habit of consistent, reusable HTML structure that those tools assume you already have.
Get the chunks right in plain HTML first. Everything else stacks on top more cleanly.

