On this page
Final project - Personal portfolio page
Final project: Personal portfolio
In this final lesson, we are going to build a complete personal portfolio using everything you have learned in the course. This project integrates:
- Semantic structure (header, main, footer, article, section)
- Navigation with internal anchors
- Images with alternative text
- Accessible skills table
- Contact form with HTML5 validation
- Meta tags for SEO and social media
- Accessibility (skip link, aria-labels, hierarchical headings)
Planning the structure
Before writing code, let's plan the portfolio sections:
- Header — Logo/name + main navigation
- Hero — Brief introduction with call to action
- About me — Photo, description, and personal details
- Projects — Cards with completed projects
- Skills — Table with technologies and skill levels
- Contact — Complete contact form
- Footer — Social media links and copyright
Document map
html
head (meta tags, title, description, og tags)
body
skip-link
header > nav
main
section#hero
section#about-me
section#projects
section#skills
section#contact
footer > navStep 1: Head with meta tags
The <head> should include all the essential meta tags we learned:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Portfolio | Your Name</title>
<meta name="description" content="Portfolio with my projects and skills.">
<meta property="og:title" content="My Portfolio">
<meta property="og:description" content="Discover my web projects.">
<meta property="og:type" content="website">
</head>Step 2: Header and navigation
The navigation uses internal anchors to scroll to each section:
<header>
<nav aria-label="Main navigation">
<a href="#">Your Name</a>
<ul>
<li><a href="#about-me">About me</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#skills">Skills</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>Do not forget the aria-label so that screen readers can identify the purpose of the navigation.
Step 3: Hero section
The hero section is the first thing the visitor sees. It should communicate who you are and what you do in a few words:
<section aria-labelledby="hero-title">
<h1 id="hero-title">Hi, I'm Your Name</h1>
<p>Junior web developer passionate about accessibility.</p>
<a href="#projects">View my projects</a>
</section>We use aria-labelledby to associate the section with its heading, which improves screen reader navigation.
Step 4: Projects as articles
Each project is independent content, so we use <article>:
<section id="projects">
<h2>My projects</h2>
<article>
<h3>Project name</h3>
<p>Project description and what I learned.</p>
<ul>
<li>Technology 1</li>
<li>Technology 2</li>
</ul>
<a href="#" target="_blank" rel="noopener">View project</a>
</article>
</section>Step 5: Skills table
The skills table applies everything we learned about accessible tables:
<table>
<caption>My technical skills</caption>
<thead>
<tr>
<th scope="col">Technology</th>
<th scope="col">Level</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">HTML5</th>
<td>Intermediate</td>
</tr>
</tbody>
</table>Remember to include <caption> and scope on every <th> for accessibility.
Step 6: Contact form
The form applies everything we learned about forms and validation:
<form action="/api/contact" method="post">
<fieldset>
<legend>Send your message</legend>
<label for="name">Name *</label>
<input type="text" id="name" name="name" required minlength="2">
<label for="email">Email *</label>
<input type="email" id="email" name="email" required>
<label for="message">Message *</label>
<textarea id="message" name="message" required minlength="20" rows="5"></textarea>
<button type="submit">Send</button>
</fieldset>
</form>Step 7: Accessible footer
The footer includes a second navigation with social media links:
<footer>
<nav aria-label="Social media">
<ul>
<li><a href="https://github.com/your-username" target="_blank" rel="noopener">GitHub</a></li>
<li><a href="https://linkedin.com/in/your-profile" target="_blank" rel="noopener">LinkedIn</a></li>
</ul>
</nav>
<p>© 2025 Your Name</p>
</footer>Validation checklist
Before considering your project complete, verify each point:
Structure
- Has
<!DOCTYPE html>and<html lang="en"> - The
<head>includes charset, viewport, title, and description - There is only one
<h1>on the entire page - Headings follow hierarchical order (h1 > h2 > h3)
- Uses semantic elements (header, main, nav, article, section, footer)
Accessibility
- Has a skip link to the main content
- All images have an appropriate
altattribute - All inputs have an associated
<label> -
<nav>elements have a descriptivearia-label - Table
<th>elements have thescopeattribute
SEO
- The
<title>is descriptive and unique - The
<meta description>summarizes the content - Includes basic Open Graph meta tags
- The canonical URL is defined
Form
- Required fields have the
requiredattribute - Uses appropriate input types (email, tel, etc.)
- Includes
autocompleteon relevant fields - Fields have validation with
minlength/maxlength
Next steps
You have completed the HTML from Scratch course. Now you know how to create web pages that are structured, accessible, and optimized for search engines. The natural next step is to learn CSS to give your pages visual styling, followed by JavaScript to add interactivity.
Your current portfolio is functional but has no styles. When you complete the CSS course, you will be able to transform it into a visually appealing page while maintaining all the semantic and accessible structure you built here.
Congratulations! You have completed the HTML from Scratch course. Continue with CSS Fundamentals to learn how to style your pages.
<!-- General portfolio structure -->
<body>
<a href="#main" class="skip-link">Skip to content</a>
<header>
<nav aria-label="Main">
<!-- Logo + navigation menu -->
</nav>
</header>
<main id="main">
<section id="hero"><!-- Introduction --></section>
<section id="about-me"><!-- About me --></section>
<section id="projects"><!-- Projects --></section>
<section id="skills"><!-- Skills table --></section>
<section id="contact"><!-- Form --></section>
</main>
<footer>
<nav aria-label="Social media">
<!-- Social links -->
</nav>
</footer>
</body>
Sign in to track your progress