What We Build
A single-page portfolio with these sections:
- Site header with logo and navigation links
- Hero section β name, tagline, CTA button
- About section β photo and biography
- Skills section β an unordered list of technologies
- Projects section β two project articles with descriptions and links
- Contact section β a form with name, email, and message
- Footer β copyright and links
By the end you will have a real file you can open in a browser, share, and later style with CSS.
Step 1 β Semantic Document Structure
Start with the HTML boilerplate and the outer landmarks: <header>, <main>, and <footer>. Add a skip link as the very first element for keyboard accessibility.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Alex Rivera β Front-End Developer</title>
<meta name="description" content="Portfolio of Alex Rivera, a front-end developer building accessible, fast web experiences.">
<link rel="canonical" href="https://alexrivera.dev/">
</head>
<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<header><!-- Step 2 content goes here --></header>
<main id="main-content">
<!-- Steps 3β7 content goes here -->
</main>
<footer><!-- Step 8 content goes here --></footer>
</body>
</html>
Step 2 β Header with Navigation
The header contains the site name (as a linked logo) and the main navigation. Use <nav aria-label="Main navigation"> to distinguish it from other nav elements on the page.
<header>
<a href="/" class="site-logo">
<img src="images/logo.svg" alt="Alex Rivera β Portfolio">
</a>
<nav aria-label="Main navigation">
<ul>
<li><a href="#about">About</a></li>
<li><a href="#skills">Skills</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>
Step 3 β Hero Section
The hero is the first thing visitors see. Use a <section> with an aria-label, an <h1> for the name, a tagline paragraph, and an anchor styled as a CTA button.
<section id="hero" aria-label="Introduction">
<h1>Hi, I'm Alex Rivera</h1>
<p class="tagline">
Front-End Developer building accessible, fast, and beautiful web experiences.
</p>
<a href="#projects" class="cta-button">View my work</a>
<a href="cv.pdf" download class="cta-button secondary">Download CV (PDF)</a>
</section>
Step 4 β About Section
The about section has a profile photo and a biography paragraph. Use <figure> and <figcaption> for the image β this is a labelled, captioned image, not just a decorative one.
<section id="about" aria-labelledby="about-heading">
<h2 id="about-heading">About Me</h2>
<figure>
<img
src="images/alex-profile.jpg"
alt="Alex Rivera standing outdoors, smiling, wearing a blue jacket"
width="300"
height="300"
>
<figcaption>Alex Rivera, London 2026</figcaption>
</figure>
<div>
<p>
I'm a self-taught front-end developer with 3 years of experience building
web applications for startups and small businesses. I care deeply about
semantic HTML, accessibility, and performance.
</p>
<p>
When I'm not coding, I contribute to open source, write tutorials at
<a href="https://ylearner.org">ylearner.org</a>, and run a local
coding meetup in London.
</p>
</div>
</section>
Step 5 β Skills Section
A simple unordered list of skills. Group related skills if you have many by using nested lists or multiple labelled lists.
<section id="skills" aria-labelledby="skills-heading">
<h2 id="skills-heading">Skills</h2>
<h3>Languages & Markup</h3>
<ul>
<li>HTML5 β Semantic markup, accessibility, forms, SEO</li>
<li>CSS3 β Flexbox, Grid, animations, custom properties</li>
<li>JavaScript β ES2024, DOM, Fetch API, async/await</li>
<li>TypeScript</li>
</ul>
<h3>Tools & Workflow</h3>
<ul>
<li>Git & GitHub</li>
<li>VS Code</li>
<li>Figma (design collaboration)</li>
<li>Chrome DevTools (performance, accessibility, debugging)</li>
</ul>
</section>
Step 6 β Projects Section
Each project is an <article> because it is a self-contained piece of content. Include an <h3> heading, a description, a list of technologies used, and links to the live site and source code.
<section id="projects" aria-labelledby="projects-heading">
<h2 id="projects-heading">Projects</h2>
<article>
<h3>AccessiCheck β WCAG Audit Tool</h3>
<p>
A browser extension that scores pages against WCAG 2.1 AA criteria,
highlights failing elements, and generates a downloadable report.
Used by over 2,000 developers.
</p>
<h4>Technologies</h4>
<ul>
<li>JavaScript (ES2024)</li>
<li>Chrome Extensions API</li>
<li>axe-core library</li>
</ul>
<a href="https://accessicheck.dev" rel="noopener noreferrer">Live site</a>
<a href="https://github.com/alexr/accessicheck" rel="noopener noreferrer">Source code</a>
</article>
<article>
<h3>Weatherly β Minimal Weather App</h3>
<p>
A weather Progressive Web App with offline support, location-based
forecasts, and a perfect Lighthouse performance score (100/100).
</p>
<h4>Technologies</h4>
<ul>
<li>HTML5</li>
<li>CSS Custom Properties</li>
<li>Fetch API + Service Worker</li>
<li>OpenWeather API</li>
</ul>
<a href="https://weatherly.alexrivera.dev" rel="noopener noreferrer">Live site</a>
<a href="https://github.com/alexr/weatherly" rel="noopener noreferrer">Source code</a>
</article>
</section>
Step 7 β Contact Section
A contact form with name, email, and message. All fields labelled, all required. A brief introduction paragraph before the form sets context.
<section id="contact" aria-labelledby="contact-heading">
<h2 id="contact-heading">Get in Touch</h2>
<p>I'm currently open to freelance and full-time opportunities.
Send me a message and I'll get back to you within 24 hours.</p>
<form action="https://formspree.io/f/your-form-id" method="POST">
<div>
<label for="contact-name">Full name</label>
<input type="text" id="contact-name" name="name"
required autocomplete="name"
placeholder="e.g. Sam Williams">
</div>
<div>
<label for="contact-email">Email address</label>
<input type="email" id="contact-email" name="email"
required autocomplete="email"
placeholder="e.g. sam@example.com">
</div>
<div>
<label for="contact-message">Message</label>
<textarea id="contact-message" name="message"
rows="6" required
placeholder="Tell me about your projectβ¦"></textarea>
</div>
<button type="submit">Send message</button>
</form>
</section>
Complete Final HTML
Here is the entire portfolio page as a single file, ready to save as index.html and open in a browser.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Alex Rivera β Front-End Developer</title>
<meta name="description" content="Portfolio of Alex Rivera, a front-end developer building accessible, fast web experiences.">
<link rel="canonical" href="https://alexrivera.dev/">
<meta property="og:type" content="website">
<meta property="og:title" content="Alex Rivera β Front-End Developer">
<meta property="og:url" content="https://alexrivera.dev/">
<meta property="og:image" content="https://alexrivera.dev/images/og-cover.jpg">
</head>
<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<header>
<a href="/" class="site-logo">
<img src="images/logo.svg" alt="Alex Rivera β Portfolio">
</a>
<nav aria-label="Main navigation">
<ul>
<li><a href="#about">About</a></li>
<li><a href="#skills">Skills</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>
<main id="main-content">
<section id="hero" aria-label="Introduction">
<h1>Hi, I'm Alex Rivera</h1>
<p class="tagline">Front-End Developer building accessible, fast, and beautiful web experiences.</p>
<a href="#projects">View my work</a>
<a href="cv.pdf" download>Download CV</a>
</section>
<section id="about" aria-labelledby="about-heading">
<h2 id="about-heading">About Me</h2>
<figure>
<img src="images/alex-profile.jpg"
alt="Alex Rivera standing outdoors, smiling, wearing a blue jacket"
width="300" height="300">
<figcaption>Alex Rivera, London 2026</figcaption>
</figure>
<div>
<p>I'm a self-taught front-end developer with 3 years of experience building web applications for startups and small businesses. I care deeply about semantic HTML, accessibility, and performance.</p>
<p>When I'm not coding, I contribute to open source, write tutorials at <a href="https://ylearner.org">ylearner.org</a>, and run a local coding meetup in London.</p>
</div>
</section>
<section id="skills" aria-labelledby="skills-heading">
<h2 id="skills-heading">Skills</h2>
<h3>Languages & Markup</h3>
<ul>
<li>HTML5</li>
<li>CSS3 β Flexbox, Grid, Custom Properties</li>
<li>JavaScript (ES2024) / TypeScript</li>
</ul>
<h3>Tools & Workflow</h3>
<ul>
<li>Git & GitHub</li>
<li>VS Code</li>
<li>Figma</li>
<li>Chrome DevTools</li>
</ul>
</section>
<section id="projects" aria-labelledby="projects-heading">
<h2 id="projects-heading">Projects</h2>
<article>
<h3>AccessiCheck β WCAG Audit Tool</h3>
<p>A browser extension scoring pages against WCAG 2.1 AA, used by over 2,000 developers.</p>
<ul><li>JavaScript</li><li>Chrome Extensions API</li><li>axe-core</li></ul>
<a href="https://accessicheck.dev" rel="noopener noreferrer">Live site</a>
<a href="https://github.com/alexr/accessicheck" rel="noopener noreferrer">Source code</a>
</article>
<article>
<h3>Weatherly β Minimal Weather App</h3>
<p>A weather PWA with offline support, location-based forecasts, and a 100/100 Lighthouse score.</p>
<ul><li>HTML5</li><li>CSS Custom Properties</li><li>Fetch API</li><li>Service Worker</li></ul>
<a href="https://weatherly.alexrivera.dev" rel="noopener noreferrer">Live site</a>
<a href="https://github.com/alexr/weatherly" rel="noopener noreferrer">Source code</a>
</article>
</section>
<section id="contact" aria-labelledby="contact-heading">
<h2 id="contact-heading">Get in Touch</h2>
<p>Open to freelance and full-time opportunities. I'll reply within 24 hours.</p>
<form action="https://formspree.io/f/your-form-id" method="POST">
<div>
<label for="contact-name">Full name</label>
<input type="text" id="contact-name" name="name" required autocomplete="name">
</div>
<div>
<label for="contact-email">Email address</label>
<input type="email" id="contact-email" name="email" required autocomplete="email">
</div>
<div>
<label for="contact-message">Message</label>
<textarea id="contact-message" name="message" rows="6" required></textarea>
</div>
<button type="submit">Send message</button>
</form>
</section>
</main>
<footer>
<p>© 2026 Alex Rivera. All rights reserved.</p>
<nav aria-label="Footer links">
<ul>
<li><a href="https://github.com/alexr" rel="noopener noreferrer">GitHub</a></li>
<li><a href="https://linkedin.com/in/alexr" rel="noopener noreferrer">LinkedIn</a></li>
<li><a href="/privacy.html">Privacy</a></li>
</ul>
</nav>
</footer>
</body>
</html>
π Summary
- The portfolio uses a logical landmark structure:
<header>,<main>,<footer>with<section>and<article>inside<main>. - Every interactive section is labelled with
aria-labelledbypointing to its<h2>, making it navigable by screen reader users. - The profile photo uses
<figure>and<figcaption>β a labelled image, not a decorative one. - Each project is wrapped in
<article>β self-contained content that makes sense independently. - The contact form has
for/idlinked labels andautocompleteattributes on all inputs. - The skip link and
id="main-content"on<main>let keyboard users bypass the header navigation.
FAQ
How do I host my portfolio for free?
GitHub Pages is the most popular free static hosting option for beginners. Create a GitHub repository named yourusername.github.io, push your HTML files, and your site is live at https://yourusername.github.io within minutes. Other free options include Netlify (drag-and-drop deploy), Vercel (automatic deploys from GitHub), and Cloudflare Pages.
How do I make the contact form actually send emails?
For a static HTML file with no backend server, use a form handling service. Formspree is the most popular β sign up for a free account, create a form, and replace the action URL with your Formspree endpoint. The form submissions arrive in your email. Other options include Netlify Forms (zero configuration if hosted on Netlify) and EmailJS.
When should I add CSS to this portfolio?
The HTML structure in this project is complete and valid. Now is the perfect time to add CSS β either write your own from scratch, or work through the ylearner CSS course to learn Flexbox and Grid, then come back and style each section. Having solid semantic HTML first means your CSS will be much easier to write, because the structure is already logical.