013: Mini Project I
Learning outcomes
By the end of this lesson, you can combine the course concepts into a complete personal profile site; organize files and relative links; implement navigation, introduction/hero content, about, skills, projects, and contact; and justify semantic, accessibility, and data-collection choices without prioritizing visual polish.
Prerequisites and retrieval
Bring the 012 content brief and architecture. Retrieve the roles of main, section, article, link versus button, useful alt, label/name, and client/server validation. Today integrates them; it should not introduce a new visual framework.
Terminology
- Mini project: a bounded integration task demonstrating several skills together (course term).
- Acceptance criteria: observable conditions the project must satisfy (course term).
- Hero: design term for prominent introductory content, not an HTML element (course term).
- Project card: visual term; semantically it may be an
articleif self-contained (course term). - Placeholder content: temporary content clearly marked for replacement, never misleading personal data (course term).
- File organization: predictable naming and folders for documents/assets (course term).
- Definition of done: agreed implementation and verification checklist (course term).
- Scope: what the project includes and deliberately excludes (course term).
- Hero (design pattern): "Prominent introductory content at the top of a page — a design pattern, not an HTML element." — Source: MDN: Structuring content — intuitive note: use section with heading, not a hero element
- Portfolio architecture (local): "The file/folder and page structure for a portfolio site, demonstrating integration of headings, landmarks, links, media, and forms." — Source: WHATWG HTML Living Standard applied via course file plan
Project brief and mental model
Build a personal site that answers three visitor questions:
- Who is this person and what do they do?
- What skills and projects demonstrate it?
- How can I contact them?
Treat the site as a structured argument, not a collection of boxes. The introduction states the claim, About adds context, Skills gives a concise inventory, Projects provides evidence, and Contact offers the next action. HTML expresses that flow before CSS.
Acceptance criteria
index.html,about.html, andcontact.htmlload and link correctly.- Every page has doctype, correct language, UTF-8, viewport, and a unique descriptive title.
- Consistent primary navigation identifies the current page.
- Each page has one visible
mainand a logicalh1-led hierarchy. - Home includes introduction, About, Skills, Projects, and Contact sections.
- At least two project entries use
article, useful text, and meaningful links. - Images have context-appropriate
altand real width/height. - Contact has a labeled, grouped, minimally validated form with fictional endpoint.
- Native links/buttons/controls are keyboard operable.
- Markup passes the Nu checker with warnings understood, not blindly suppressed.
- No obsolete presentational markup, secrets, unnecessary ARIA, or copied code you cannot explain.
File plan
portfolio/ ├─ index.html ├─ about.html ├─ contact.html ├─ images/ │ ├─ profile.webp │ └─ weather-project.webp └─ projects/ ├─ weather.html └─ schedule.html
Use lowercase, hyphenated names and forward slashes in URLs. Do not include spaces, random version suffixes, or case differences. Image/media files should be optimized and licensed. Avoid adding an asset merely to fill a box.
Project quality gates
Treat the project as complete only when it passes four gates:
- Structure: every page has a valid document skeleton, useful title, logical heading hierarchy, and appropriate landmarks.
- Navigation: every internal link resolves from the file where it appears, current-page state is understandable, and link text makes sense out of context.
- Content: images have context-appropriate alternatives, lists/tables/forms use their native structures, and no element is chosen only for its default appearance.
- Interaction: every form control has a usable label and name, keyboard order follows the document, and browser validation is helpful without being treated as security.
A project that looks correct but fails one of these gates is not finished. This is deliberately stricter than “it opens in my browser.”
Guided example: build Home progressively
Start with the skeleton and shared regions, then add one section at a time. This is a complete baseline:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Portfolio | Asha Rao</title>
</head>
<body>
<header>
<p><a href="index.html">Asha Rao</a></p>
<nav aria-label="Primary">
<ul>
<li><a href="index.html" aria-current="page">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
</header>
<main>
<section>
<h1>Building clear, useful websites with semantic HTML</h1>
<p>I plan content first and use semantic HTML as the foundation.</p>
<p><a href="#projects">Review my projects</a></p>
</section>
<section>
<h2>About me</h2>
<figure>
<img
src="images/profile.webp"
alt="Asha Rao planning a website structure on a whiteboard"
width="800"
height="600">
<figcaption>Planning hierarchy before presentation.</figcaption>
</figure>
<p>I focus on clear, accessible foundations and document each project.</p>
<p><a href="about.html">More about Asha</a></p>
</section>
<section>
<h2>Skills</h2>
<ul>
<li>Semantic document structure</li>
<li>Accessible links, media, tables, and forms</li>
<li>HTML conformance and keyboard testing</li>
</ul>
</section>
<section id="projects">
<h2>Projects</h2>
<article>
<h3>Weather summary</h3>
<img
src="images/weather-project.webp"
alt="Weather summary showing Chennai at 31 degrees Celsius and cloudy"
width="1440"
height="900"
loading="lazy">
<p>A structured forecast page with meaningful media alternatives.</p>
<p><a href="projects/weather.html">Weather summary project details</a></p>
</article>
<article>
<h3>Course schedule</h3>
<p>An accessible data table with scoped row and column headings.</p>
<p><a href="projects/schedule.html">Course schedule project details</a></p>
</article>
</section>
<section>
<h2>Contact</h2>
<p>Have constructive feedback or a project question?</p>
<p><a href="contact.html">Send Asha a message</a></p>
</section>
</main>
<footer>
<p><small>Copyright 2026 Asha Rao</small></p>
</footer>
</body>
</html>
“Hero” is represented by a normal introductory section because HTML has no hero element. The project fragment targets a real section. Project articles remain understandable if syndicated separately. The project image is lazy because it follows substantial introduction; profile loading depends on placement and should be measured.
After each section, save, reload, inspect headings, and test links. Small verification cycles make errors easier to locate than writing everything and testing at the end.
Intermediate example: complete Contact
Use the same header/footer, update title, h1, and aria-current, then place:
<main>
<h1>Contact Asha Rao</h1>
<p>Required fields are marked “required.” Do not send sensitive information.</p>
<form action="/contact" method="post">
<p>
<label for="name">Name (required)</label>
<input type="text" id="name" name="name" autocomplete="name" required maxlength="100">
</p>
<p>
<label for="email">Email (required)</label>
<input type="email" id="email" name="email" autocomplete="email" required maxlength="254">
</p>
<p>
<label for="topic">Topic (required)</label>
<select id="topic" name="topic" required>
<option value="">Choose a topic</option>
<option value="project">Project question</option>
<option value="feedback">Portfolio feedback</option>
</select>
</p>
<fieldset>
<legend>Reply preference</legend>
<input type="radio" id="reply-email" name="reply" value="email" required>
<label for="reply-email">Email reply</label>
<input type="radio" id="reply-none" name="reply" value="none">
<label for="reply-none">No reply needed</label>
</fieldset>
<p id="message-help">Enter 20 to 1000 characters.</p>
<p>
<label for="message">Message (required)</label>
<textarea id="message" name="message" rows="8" cols="50" required minlength="20" maxlength="1000" aria-describedby="message-help"></textarea>
</p>
<button type="submit">Send message</button>
</form>
</main>
The endpoint is illustrative until a server exists. Add a visible note rather than pretending submissions are stored. Do not collect phone/address/date of birth without a project need. Native validation helps users but is not security.
Advanced optional extension: project detail architecture
From projects/weather.html, shared navigation links use ../. Build a project article with problem, approach, result, screenshot figure, and links. Include a small data table only if actual comparable forecast data exists. Avoid adding every learned element as decoration.
Add a skip link only when CSS later makes it usable visually on focus:
<a href="#main-content">Skip to main content</a>
...
<main id="main-content">
It is valid useful HTML now, but visual focus treatment is necessary in the styled project. Do not use positive tabindex or scripts to move focus.
Common mistakes and debugging
- Building all pages before testing: verify section/page increments.
- Copying Home unchanged: update title, current link, main heading, IDs, and paths.
- Empty links or
#placeholders: create real destinations or omit unfinished links. - Every container is a section: keep semantics tied to named themes.
- Alt duplicates captions/paragraphs: preserve purpose without repetition.
- Form appears to work without server: state endpoint limitations honestly.
- Root-relative links in subdirectory deployment: prefer tested document-relative paths for this project.
- Visual polish hides incomplete structure: acceptance criteria prioritize content and operation.
Accessibility, security, and performance
Test page title/language, headings, landmarks, link purpose, image alternatives, label/group associations, keyboard focus, zoom, and errors. Do not claim full WCAG conformance from this scope. Use native controls and limited ARIA only where it adds state/description.
Publish only consented information and licensed media; remove metadata; never include credentials/comments with secrets. Use HTTPS and server validation when the form becomes real. Optimize images, reserve dimensions, avoid autoplay and unnecessary scripts, and measure rather than counting requests alone.
Tiered exercises
Level 1: skeleton
Create the folder tree and three valid pages with unique metadata, consistent navigation, current-page state, one main, and footer.
Level 2: complete Home and Contact
Implement every acceptance-criteria section and the complete contact form. Use real personal content only with consent; otherwise use clearly fictional content.
Level 3: detail and verify
Build two project detail pages, run link/keyboard/image/form/conformance checks, and explain five semantic decisions in your own words.
Level 1: use the guided skeleton on each page. About's current link moves to About; Contact's moves to Contact. Nested project links begin ../. Every title and h1 is page-specific.
Level 2: the guided Home plus intermediate Contact are complete solutions. About can reuse relevant Home content expanded into one page. Replace fictional assets with optimized licensed files and accurate dimensions/alt decisions.
Level 3: each project page contains a project article, logical headings, problem/approach/result, meaningful back navigation, and appropriate media/data only. Verification reports zero unexplained Nu errors, every internal link works, keyboard order follows source, image purposes survive failure, labels activate controls, and invalid test cases behave as expected. Your explanations should cover article, heading levels, alt context, method/name, and client-validation limits.
Recap and exit questions
The mini project integrates purpose, hierarchy, semantics, media, navigation, and forms. Completion means tested structure and explainable choices, not visual decoration.
- Why is hero a content pattern rather than an HTML element?
- What makes a project entry an article?
- Which copied page values must change?
- Why must the form endpoint limitation be stated?
- What evidence shows the project is done?
Try it with your own example
You have now built almost every piece of Rina's site across the last twelve lessons in isolation — the skeleton in 002, the story in 003, the links in 004, photos in 005, semantics in 006, the hours table in 007, the newsletter and cake forms in 008–010, and you audited it in 011–012. This is the lesson where you stop practicing pieces and actually assemble them into one real site, the same way you're assembling Asha's.
Set yourself the same acceptance criteria as the main brief, adapted to a business site instead of a personal one:
index.html,menu.html, andorder.htmlexist and link to each other correctly, using the paths you deliberately broke and fixed back in lesson 004.- The opening-hours table from lesson 007 lives on
index.html, complete withcaptionandscope. - The cake-order form from lessons 009–010 lives on
order.html, complete withrequiredand grouped controls. - Every image carries the
altdecisions you practiced in lesson 005 — not placeholder text. - Nothing on the page is a
divpretending to be a button, per lesson 011.
Building Rina's site end to end, using only what you already wrote for her in earlier lessons, is a stronger test of whether the concepts actually transferred than reading one more example would be. If a piece doesn't fit cleanly, that's useful information — go back to that lesson and ask what assumption you made about "the portfolio" that doesn't hold for "the bakery."
