013: Mini Project I
Learning outcomes
By the end of this lesson, you can bring the course concepts together in a complete personal profile site. You will organize files and relative links, build navigation and introduction/hero content, and add About, Skills, Projects, and Contact areas. You will also be able to explain your semantic, accessibility, and data-collection decisions. The goal is a sound HTML foundation, not visual polish.
Prerequisites and retrieval
Have the 012 content brief and architecture beside you. Before you start, bring back the roles of main, section, and article; the difference between a link and a button; useful alt text; label/name associations; and client-side versus server-side validation. This lesson is an integration exercise for those ideas. It does 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 questions for a visitor:
- Who is this person and what do they do?
- What skills and projects demonstrate it?
- How can I contact them?
Think of the site as a structured argument rather than a set of visual boxes. The introduction makes the claim, About supplies context, Skills gives a concise inventory, Projects provides evidence, and Contact presents the next action. HTML should express that sequence before CSS is involved.
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. Avoid spaces, arbitrary version suffixes, and case differences. Optimize and license image/media files, and do not add an asset just to occupy an empty box.
Project quality gates
Call the project complete only after it clears 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, the current-page state is understandable, and link text still makes sense out of context.
- Content: images have context-appropriate alternatives, lists/tables/forms use their native structures, and no element was selected only for its default appearance.
- Interaction: every form control has a usable label and name, keyboard order follows the document, and browser validation helps the user without being mistaken for security.
A page can look correct and still fail one of these gates. Opening in a browser is only a first check, not a definition of done.
Guided example: build Home progressively
Start with the document skeleton and the regions shared by the other pages. Add one section, save, and test before moving to the next. The following 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” describes the prominent introduction, but HTML has no hero element. Here it is an ordinary section with a heading. The #projects fragment points to a real section, and each project article remains intelligible if it is syndicated on its own. The project image is lazy-loaded because it comes after a substantial introduction. Whether the profile image should also be deferred depends on its placement and should be measured.
After every section, save, reload, inspect the headings, and test the links. These small verification cycles narrow down mistakes much more effectively than waiting until the entire site is written.
Intermediate example: complete Contact
Keep the same header and footer, but change the title, h1, and aria-current value for this page. Then add the following form:
<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>
Until a server exists, /contact is only an illustrative endpoint. Say that visibly rather than implying that submissions are being stored. Collect no phone number, address, or date of birth unless the project has a real need for it. Native validation improves the user experience; it is not a security boundary, so a real server must validate again.
Advanced optional extension: project detail architecture
On projects/weather.html, shared navigation links need ../ because the document is one directory deeper. Structure the project as an article with a problem, approach, result, screenshot figure, and useful links. Add a small data table only when you have actual comparable forecast data. A learned element does not need to be added merely as decoration.
You can add a skip link once later CSS makes its focus state visibly usable:
<a href="#main-content">Skip to main content</a>
...
<main id="main-content">
This is valid and useful HTML now, but the styled project also needs visible focus treatment. Do not use a positive tabindex or scripts to move focus.
Common mistakes and debugging
- Building all pages before testing: verify each section and page as you add it.
- Copying Home unchanged: update the title, current link, main heading, IDs, and paths.
- Empty links or
#placeholders: create real destinations or leave unfinished links out. - Every container is a section: use sectioning elements for named themes, not for every wrapper.
- Alt duplicates captions/paragraphs: make the alternative serve the image's purpose without repeating nearby text.
- Form appears to work without server: state the endpoint's limitation honestly.
- Root-relative links in subdirectory deployment: for this project, prefer document-relative paths that you have tested.
- Visual polish hides incomplete structure: acceptance criteria put content and operation first.
Accessibility, security, and performance
Test the page title and language, headings, landmarks, link purpose, image alternatives, label/group associations, keyboard focus, zoom behavior, and error states. This scope is not enough to claim full WCAG conformance. Prefer native controls, and use ARIA sparingly, only when it adds a needed state or description.
Publish only information that has consent and media that is licensed; remove metadata, and never leave credentials or secret comments in the files. When the form becomes real, use HTTPS and validate on the server. Optimize images, reserve their dimensions, avoid autoplay and unnecessary scripts, and measure performance instead of assuming that request count alone tells you what is fast.
Tiered exercises
Level 1: skeleton
Create the folder tree and three valid pages. Give them unique metadata, consistent navigation, current-page state, one main, and a 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 label the content clearly as fictional.
Level 3: detail and verify
Build two project detail pages. Run link, keyboard, image, form, and conformance checks, then explain five semantic decisions in your own words.
Level 1: use the guided skeleton on each page. Move About's current link to About and Contact's to Contact. Nested project links begin with ../. Give every page a page-specific title and h1.
Level 2: the guided Home and intermediate Contact examples are complete solutions. About can reuse the relevant Home content and expand it into its own page. Replace fictional assets with optimized, licensed files, and make sure the dimensions and alt decisions are accurate.
Level 3: each project page contains a project article, logical headings, problem/approach/result content, meaningful back navigation, and only appropriate media or data. Verification should report zero unexplained Nu errors; every internal link should work; keyboard order should follow the source; image purpose should survive image failure; labels should activate their controls; and invalid test cases should behave as expected. Your explanation should cover article, heading levels, contextual alt, method/name, and the limits of client validation.
Recap and exit questions
This mini project brings purpose, hierarchy, semantics, media, navigation, and forms into one site. Done means the structure has been tested and the choices can be explained; visual decoration is secondary.
- 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
Across the previous twelve lessons, you built nearly every part of Rina's site separately: the skeleton in 002, the story in 003, links in 004, photos in 005, semantics in 006, the hours table in 007, the newsletter and cake forms in 008–010, and the audits in 011–012. Now assemble those pieces into one working site, just as you assembled Asha's.
Use the main brief's acceptance criteria, adapted from a personal portfolio to a business site:
index.html,menu.html, andorder.htmlexist and link to one another correctly, using the paths you deliberately broke and repaired in lesson 004.- The opening-hours table from lesson 007 is on
index.html, complete withcaptionandscope. - The cake-order form from lessons 009–010 is on
order.html, complete withrequiredand grouped controls. - Every image reflects the
altdecisions practiced in lesson 005, rather than placeholder text. - Nothing is a
divpretending to be a button, as lesson 011 demonstrated.
Building Rina's site end to end, using only what you already wrote for her, tests transfer more strongly than another isolated example. If a piece does not fit cleanly, treat that as evidence. Return to the earlier lesson and examine which assumption about “the portfolio” does not hold for “the bakery.”
