HTML5 Fundamentals

Building a Complete Multi-Page Website

40 min Lesson 18 of 18

Project Overview

In this final lesson, you will bring together everything you have learned to build a complete multi-page portfolio website from scratch. The project includes three pages: a homepage with hero, about, and skills sections; a dedicated about page with your background story; and a contact page with a working form. This exercise reinforces semantic HTML, proper document structure, navigation, linking, images, forms, meta tags, and accessibility -- all without any CSS or JavaScript.

Planning Your Site Structure

Before writing any code, plan your folder structure and page layout. A well-organized project is easier to maintain and scale. Here is the recommended structure for this project:

Example: Project Folder Structure

my-portfolio/
    index.html
    about.html
    contact.html
    images/
        profile.jpg
        project-1.jpg
        project-2.jpg

Each HTML file represents one page of your website. The images/ folder keeps all media assets organized in one place. As your projects grow, you might add folders for css/ and js/, but for now we focus purely on HTML.

Building the Homepage: index.html

The homepage is the first page visitors see. It should introduce who you are and what you do. We will structure it with a hero section, an about preview, and a skills section, all using semantic HTML elements.

Example: Complete Homepage Structure

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Portfolio of Jane Smith - Web Developer specializing in HTML, CSS, and JavaScript.">
    <meta name="keywords" content="web developer, portfolio, HTML, CSS, JavaScript">
    <meta name="author" content="Jane Smith">
    <title>Jane Smith - Web Developer Portfolio</title>
</head>
<body>
    <a href="#main-content" class="skip-link">Skip to main content</a>

    <header>
        <nav aria-label="Main navigation">
            <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 id="main-content">
        <section aria-labelledby="hero-heading">
            <h1 id="hero-heading">Hi, I am Jane Smith</h1>
            <p>A web developer passionate about building clean, accessible websites.</p>
            <a href="contact.html">Get in touch</a>
        </section>

        <section aria-labelledby="about-heading">
            <h2 id="about-heading">About Me</h2>
            <img src="images/profile.jpg" alt="Jane Smith smiling at her desk" width="300" height="300">
            <p>I am a self-taught developer with a love for semantic HTML and accessible design. I believe the web should be open to everyone.</p>
            <a href="about.html">Read my full story</a>
        </section>

        <section aria-labelledby="skills-heading">
            <h2 id="skills-heading">Skills</h2>
            <ul>
                <li>HTML5 and Semantic Markup</li>
                <li>Web Accessibility (WCAG 2.1)</li>
                <li>Responsive Design Principles</li>
                <li>SEO Best Practices</li>
                <li>Version Control with Git</li>
            </ul>
        </section>
    </main>

    <footer>
        <p>Copyright 2025 Jane Smith. All rights reserved.</p>
    </footer>
</body>
</html>
Note: The aria-current="page" attribute on the Home link tells screen readers which page the user is currently viewing. Update this attribute on each page to match the active navigation item.

Building the About Page: about.html

The about page expands on your background story. It uses the same navigation structure for consistency, ensuring visitors can move between pages easily. Notice how the navigation markup is identical across all pages -- only the aria-current attribute changes.

Example: About Page Structure

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Learn about Jane Smith - her journey into web development and professional background.">
    <title>About - Jane Smith</title>
</head>
<body>
    <a href="#main-content" class="skip-link">Skip to main content</a>

    <header>
        <nav aria-label="Main navigation">
            <ul>
                <li><a href="index.html">Home</a></li>
                <li><a href="about.html" aria-current="page">About</a></li>
                <li><a href="contact.html">Contact</a></li>
            </ul>
        </nav>
    </header>

    <main id="main-content">
        <h1>About Me</h1>

        <section>
            <h2>My Journey</h2>
            <p>I started learning web development in 2023, driven by curiosity about how websites work. What began as a hobby quickly grew into a passion for building accessible, well-structured web experiences.</p>
        </section>

        <section>
            <h2>Education</h2>
            <ul>
                <li>Self-taught through online courses and documentation</li>
                <li>Completed freeCodeCamp Responsive Web Design certification</li>
                <li>Studied web accessibility through W3C resources</li>
            </ul>
        </section>

        <section>
            <h2>What Drives Me</h2>
            <p>I believe every website should be usable by everyone, regardless of ability. Accessibility is not an afterthought -- it is a core part of quality web development.</p>
            <a href="contact.html">Let us work together</a>
        </section>
    </main>

    <footer>
        <p>Copyright 2025 Jane Smith. All rights reserved.</p>
    </footer>
</body>
</html>

Building the Contact Page: contact.html

The contact page features an accessible form with proper labels, input types, and validation attributes. Every form field has a programmatically associated label, required fields are marked, and the form uses native HTML validation.

Example: Contact Page with Accessible Form

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Contact Jane Smith for web development projects and collaborations.">
    <title>Contact - Jane Smith</title>
</head>
<body>
    <a href="#main-content" class="skip-link">Skip to main content</a>

    <header>
        <nav aria-label="Main navigation">
            <ul>
                <li><a href="index.html">Home</a></li>
                <li><a href="about.html">About</a></li>
                <li><a href="contact.html" aria-current="page">Contact</a></li>
            </ul>
        </nav>
    </header>

    <main id="main-content">
        <h1>Contact Me</h1>
        <p>Have a project in mind? Fill out the form below and I will get back to you within 48 hours.</p>

        <form action="/submit" method="post">
            <fieldset>
                <legend>Your Information</legend>

                <label for="full-name">Full Name (required)</label>
                <input type="text" id="full-name" name="full-name" required
                       autocomplete="name" placeholder="Jane Smith">

                <label for="email">Email Address (required)</label>
                <input type="email" id="email" name="email" required
                       autocomplete="email" placeholder="jane@example.com">

                <label for="phone">Phone Number (optional)</label>
                <input type="tel" id="phone" name="phone"
                       autocomplete="tel" placeholder="+1 555 123 4567">
            </fieldset>

            <fieldset>
                <legend>Your Message</legend>

                <label for="subject">Subject (required)</label>
                <select id="subject" name="subject" required>
                    <option value="">-- Choose a topic --</option>
                    <option value="project">New Project</option>
                    <option value="collaboration">Collaboration</option>
                    <option value="question">General Question</option>
                </select>

                <label for="message">Message (required)</label>
                <textarea id="message" name="message" rows="6" required
                          minlength="20" placeholder="Tell me about your project..."></textarea>
            </fieldset>

            <button type="submit">Send Message</button>
        </form>
    </main>

    <footer>
        <p>Copyright 2025 Jane Smith. All rights reserved.</p>
    </footer>
</body>
</html>
Pro Tip: Always use specific input types like type="email" and type="tel" instead of generic type="text". This triggers appropriate keyboards on mobile devices, enables built-in browser validation, and helps password managers and autofill tools work correctly.

Consistent Navigation Across Pages

A consistent navigation structure is essential for usability. Users expect the navigation to appear in the same location on every page with the same links in the same order. The aria-current="page" attribute should be updated on each page to indicate the current page. This consistency helps all users, especially those using screen readers who rely on predictable page structure.

Linking Pages Together

Since all three HTML files are in the same folder, you can use relative paths to link between them. Use href="about.html" rather than absolute paths. For linking to specific sections within a page, use fragment identifiers like href="index.html#skills-heading". Always use descriptive link text that makes sense out of context -- screen readers often navigate by listing all links on a page.

Adding and Optimizing Images

Place all images in the images/ folder and reference them with relative paths. Always include width and height attributes to prevent layout shifts as the page loads. Write descriptive alt text for informative images, and use alt="" for purely decorative ones. Consider using the <figure> and <figcaption> elements to provide visible captions for important images.

Example: Image with Figure and Caption

<figure>
    <img src="images/project-1.jpg"
         alt="Screenshot of a weather dashboard showing temperature and forecast data"
         width="600" height="400">
    <figcaption>Weather Dashboard -- my first web development project.</figcaption>
</figure>

Meta Tags for SEO

Every page should include essential meta tags in the <head>. The charset and viewport meta tags are required for proper rendering. The description meta tag provides a summary that search engines display in results. The title element should be unique and descriptive for every page, including your name or brand for recognition.

Form Validation with HTML

Native HTML validation attributes provide immediate feedback without JavaScript. The required attribute prevents empty submissions. The type="email" attribute validates email format. The minlength attribute enforces minimum character counts. The pattern attribute accepts regular expressions for custom validation rules. Browsers display built-in error messages that are already accessible to screen readers.

Performing an Accessibility Audit

Before considering your site complete, verify the following checklist:

  • Every page has exactly one <h1> element and a logical heading hierarchy.
  • All images have appropriate alt attributes.
  • All form controls have associated <label> elements.
  • The entire site is navigable using only a keyboard.
  • Skip navigation links are present on every page.
  • The lang attribute is set on the <html> element.
  • Links have descriptive text (no "click here" links).
  • The document has a meaningful <title> on every page.
Common Mistake: Copying the navigation to every page but forgetting to update the aria-current="page" attribute. This small detail makes a significant difference for screen reader users. Also, avoid using the same <title> on every page -- each page title should be unique and descriptive so users can identify pages in their browser tabs and history.

What to Learn Next

Congratulations on completing this HTML course. You now have a solid foundation in semantic, accessible HTML. Here is where to go next:

  • CSS -- Learn to style your pages with colors, fonts, layouts, and responsive design using media queries, Flexbox, and Grid.
  • JavaScript -- Add interactivity such as form validation, dynamic content, animations, and API integration.
  • Version Control -- Learn Git to track changes and collaborate with other developers.
  • Deployment -- Publish your site to the web using services like GitHub Pages or Netlify.

Practice Exercise

Build the complete three-page portfolio website described in this lesson from scratch. Start by creating the folder structure with index.html, about.html, contact.html, and an images/ folder. Customize the content to reflect your own information -- use your real name, your actual skills, and your own background story. Ensure the navigation is consistent across all three pages and update the aria-current attribute on each page. Add at least two images with proper alt text. Make sure the contact form includes three different input types and uses the required attribute on essential fields. Run a Lighthouse accessibility audit on all three pages and fix any issues until each page scores above 90. Finally, validate all three files using the W3C Markup Validation Service at validator.w3.org to confirm your HTML is error-free.