Building a Portfolio Page

Create a professional portfolio website to showcase your skills, projects, and achievements! Learn how to build a complete portfolio from scratch using semantic HTML and effective layout techniques.

Why a Portfolio Matters

A portfolio website is your digital resume—it showcases your work, demonstrates your skills, and makes you stand out to potential employers or clients. Whether you’re a designer, developer, photographer, or writer, a well-crafted portfolio is essential for your professional presence online.

Your portfolio is often the first impression someone gets of your work, so it needs to be clean, professional, and easy to navigate.

Planning Your Portfolio Structure

Before coding, plan the key sections your portfolio needs:

  1. Hero Section — Eye-catching introduction with your name and title
  2. About Section — Brief bio explaining who you are
  3. Skills Section — Technologies and tools you know
  4. Projects Section — Showcase of your best work
  5. Contact Section — Ways to get in touch

Let’s build each section step by step!

Complete Portfolio HTML Structure

Here’s the complete HTML skeleton for your portfolio:

<!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 [Your Name] - Web Developer">
<title>[Your Name] - Portfolio</title>
</head>
<body>
<!-- Navigation -->
<nav>
  <a href="#home">Home</a>
  <a href="#about">About</a>
  <a href="#skills">Skills</a>
  <a href="#projects">Projects</a>
  <a href="#contact">Contact</a>
</nav>

<!-- Hero Section -->
<header id="home">
  <h1>Your Name</h1>
  <p>Web Developer | Designer | Problem Solver</p>
</header>

<!-- About Section -->
<section id="about">
  <h2>About Me</h2>
  <p>Your bio goes here...</p>
</section>

<!-- Skills Section -->
<section id="skills">
  <h2>My Skills</h2>
  <!-- Skills content -->
</section>

<!-- Projects Section -->
<section id="projects">
  <h2>My Projects</h2>
  <!-- Project cards -->
</section>

<!-- Contact Section -->
<section id="contact">
  <h2>Get In Touch</h2>
  <!-- Contact form -->
</section>

<!-- Footer -->
<footer>
  <p>&copy; 2025 Your Name. All rights reserved.</p>
</footer>
</body>
</html>

This structure uses semantic HTML5 elements (<nav>, <header>, <section>, <footer>) for better accessibility and SEO.

Creating the Hero Section

The hero section is your portfolio’s first impression. Make it count!

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Jane Smith - Portfolio</title>
<style>
  body {
    margin: 0;
    font-family: 'Segoe UI', Tahoma, sans-serif;
  }
  
  .hero {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    text-align: center;
    padding: 100px 20px;
    min-height: 60vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
  
  .hero h1 {
    font-size: 3rem;
    margin: 0 0 20px 0;
  }
  
  .hero p {
    font-size: 1.5rem;
    margin: 0 0 30px 0;
  }
  
  .cta-button {
    background: white;
    color: #667eea;
    padding: 15px 30px;
    text-decoration: none;
    border-radius: 5px;
    font-weight: bold;
    transition: transform 0.3s;
  }
  
  .cta-button:hover {
    transform: translateY(-3px);
  }
</style>
</head>
<body>
<header class="hero" id="home">
  <h1>Jane Smith</h1>
  <p>Frontend Developer & UI Designer</p>
  <a href="#projects" class="cta-button">View My Work</a>
</header>
</body>
</html>

Key elements:

Building the About Section

Share your story and what makes you unique:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About Section</title>
<style>
  .about {
    max-width: 1200px;
    margin: 0 auto;
    padding: 80px 20px;
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: 40px;
    align-items: center;
  }
  
  .about-image {
    width: 100%;
    max-width: 300px;
    border-radius: 50%;
    box-shadow: 0 10px 30px rgba(0,0,0,0.2);
  }
  
  .about-content h2 {
    color: #333;
    font-size: 2rem;
    margin-bottom: 20px;
  }
  
  .about-content p {
    color: #666;
    line-height: 1.8;
    margin-bottom: 15px;
  }
  
  @media (max-width: 768px) {
    .about {
      grid-template-columns: 1fr;
      text-align: center;
    }
    
    .about-image {
      margin: 0 auto;
    }
  }
</style>
</head>
<body>
<section class="about" id="about">
  <div class="about-image-container">
    <img 
      src="profile-photo.jpg" 
      alt="Jane Smith profile photo" 
      class="about-image">
  </div>
  
  <div class="about-content">
    <h2>About Me</h2>
    <p>
      Hi! I'm Jane, a frontend developer with a passion for creating 
      beautiful, user-friendly websites. I specialize in HTML, CSS, 
      and JavaScript, and I love bringing designs to life through code.
    </p>
    <p>
      With 3 years of experience in web development, I've worked on 
      projects ranging from small business websites to large-scale 
      web applications. I'm always learning new technologies and 
      staying current with web development trends.
    </p>
    <p>
      When I'm not coding, you can find me hiking, reading sci-fi 
      novels, or experimenting with new recipes in the kitchen.
    </p>
  </div>
</section>
</body>
</html>

Tips for your About section:

Displaying Your Skills

Show what you can do with a clean skills grid:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Skills Section</title>
<style>
  .skills {
    background: #f8f9fa;
    padding: 80px 20px;
  }
  
  .skills h2 {
    text-align: center;
    font-size: 2.5rem;
    margin-bottom: 50px;
    color: #333;
  }
  
  .skills-grid {
    max-width: 1000px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 30px;
  }
  
  .skill-card {
    background: white;
    padding: 30px;
    border-radius: 10px;
    text-align: center;
    box-shadow: 0 5px 15px rgba(0,0,0,0.1);
    transition: transform 0.3s;
  }
  
  .skill-card:hover {
    transform: translateY(-5px);
  }
  
  .skill-icon {
    font-size: 3rem;
    margin-bottom: 15px;
  }
  
  .skill-card h3 {
    margin: 0 0 10px 0;
    color: #333;
  }
  
  .skill-level {
    color: #666;
    font-size: 0.9rem;
  }
</style>
</head>
<body>
<section class="skills" id="skills">
  <h2>My Skills</h2>
  
  <div class="skills-grid">
    <div class="skill-card">
      <div class="skill-icon">🌐</div>
      <h3>HTML5</h3>
      <p class="skill-level">Expert</p>
    </div>
    
    <div class="skill-card">
      <div class="skill-icon">🎨</div>
      <h3>CSS3</h3>
      <p class="skill-level">Expert</p>
    </div>
    
    <div class="skill-card">
      <div class="skill-icon">⚡</div>
      <h3>JavaScript</h3>
      <p class="skill-level">Advanced</p>
    </div>
    
    <div class="skill-card">
      <div class="skill-icon">⚛️</div>
      <h3>React</h3>
      <p class="skill-level">Intermediate</p>
    </div>
    
    <div class="skill-card">
      <div class="skill-icon">📱</div>
      <h3>Responsive Design</h3>
      <p class="skill-level">Expert</p>
    </div>
    
    <div class="skill-card">
      <div class="skill-icon">🎯</div>
      <h3>UI/UX Design</h3>
      <p class="skill-level">Advanced</p>
    </div>
  </div>
</section>
</body>
</html>

You can replace emoji icons with actual icon libraries like Font Awesome or use SVG icons for a more professional look.

Creating Project Cards

Showcase your work with attractive project cards:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Projects Section</title>
<style>
  .projects {
    max-width: 1200px;
    margin: 0 auto;
    padding: 80px 20px;
  }
  
  .projects h2 {
    text-align: center;
    font-size: 2.5rem;
    margin-bottom: 50px;
    color: #333;
  }
  
  .projects-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 40px;
  }
  
  .project-card {
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 5px 20px rgba(0,0,0,0.1);
    transition: transform 0.3s;
  }
  
  .project-card:hover {
    transform: translateY(-10px);
  }
  
  .project-image {
    width: 100%;
    height: 200px;
    object-fit: cover;
  }
  
  .project-content {
    padding: 25px;
  }
  
  .project-content h3 {
    margin: 0 0 15px 0;
    color: #333;
  }
  
  .project-content p {
    color: #666;
    line-height: 1.6;
    margin-bottom: 20px;
  }
  
  .project-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 20px;
  }
  
  .tag {
    background: #e9ecef;
    padding: 5px 12px;
    border-radius: 15px;
    font-size: 0.85rem;
    color: #495057;
  }
  
  .project-links {
    display: flex;
    gap: 15px;
  }
  
  .project-link {
    text-decoration: none;
    color: #667eea;
    font-weight: bold;
    transition: color 0.3s;
  }
  
  .project-link:hover {
    color: #764ba2;
  }
</style>
</head>
<body>
<section class="projects" id="projects">
  <h2>My Projects</h2>
  
  <div class="projects-grid">
    <!-- Project 1 -->
    <article class="project-card">
      <img 
        src="project1-screenshot.jpg" 
        alt="E-commerce website screenshot" 
        class="project-image">
      <div class="project-content">
        <h3>E-commerce Platform</h3>
        <p>
          A fully responsive online store with shopping cart, 
          product filters, and checkout functionality.
        </p>
        <div class="project-tags">
          <span class="tag">HTML</span>
          <span class="tag">CSS</span>
          <span class="tag">JavaScript</span>
        </div>
        <div class="project-links">
          <a href="#" class="project-link">View Live →</a>
          <a href="#" class="project-link">Source Code →</a>
        </div>
      </div>
    </article>
    
    <!-- Project 2 -->
    <article class="project-card">
      <img 
        src="project2-screenshot.jpg" 
        alt="Weather app screenshot" 
        class="project-image">
      <div class="project-content">
        <h3>Weather Dashboard</h3>
        <p>
          Real-time weather app with forecasts, location search, 
          and beautiful UI animations.
        </p>
        <div class="project-tags">
          <span class="tag">React</span>
          <span class="tag">API</span>
          <span class="tag">CSS</span>
        </div>
        <div class="project-links">
          <a href="#" class="project-link">View Live →</a>
          <a href="#" class="project-link">Source Code →</a>
        </div>
      </div>
    </article>
    
    <!-- Project 3 -->
    <article class="project-card">
      <img 
        src="project3-screenshot.jpg" 
        alt="Portfolio website screenshot" 
        class="project-image">
      <div class="project-content">
        <h3>Photography Portfolio</h3>
        <p>
          Elegant portfolio site for a professional photographer 
          with image galleries and contact forms.
        </p>
        <div class="project-tags">
          <span class="tag">HTML</span>
          <span class="tag">CSS Grid</span>
          <span class="tag">Lightbox</span>
        </div>
        <div class="project-links">
          <a href="#" class="project-link">View Live →</a>
          <a href="#" class="project-link">Source Code →</a>
        </div>
      </div>
    </article>
  </div>
</section>
</body>
</html>

Each project card should include:

Adding a Contact Section

Make it easy for people to reach you:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact Section</title>
<style>
  .contact {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 80px 20px;
  }
  
  .contact-container {
    max-width: 800px;
    margin: 0 auto;
    text-align: center;
  }
  
  .contact h2 {
    font-size: 2.5rem;
    margin-bottom: 20px;
  }
  
  .contact p {
    font-size: 1.2rem;
    margin-bottom: 40px;
  }
  
  .contact-form {
    background: white;
    padding: 40px;
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.2);
  }
  
  .form-group {
    margin-bottom: 20px;
    text-align: left;
  }
  
  .form-group label {
    display: block;
    margin-bottom: 8px;
    color: #333;
    font-weight: bold;
  }
  
  .form-group input,
  .form-group textarea {
    width: 100%;
    padding: 12px;
    border: 2px solid #e9ecef;
    border-radius: 5px;
    font-size: 1rem;
    font-family: inherit;
  }
  
  .form-group input:focus,
  .form-group textarea:focus {
    outline: none;
    border-color: #667eea;
  }
  
  .form-group textarea {
    min-height: 150px;
    resize: vertical;
  }
  
  .submit-button {
    background: #667eea;
    color: white;
    padding: 15px 40px;
    border: none;
    border-radius: 5px;
    font-size: 1.1rem;
    font-weight: bold;
    cursor: pointer;
    transition: background 0.3s;
  }
  
  .submit-button:hover {
    background: #764ba2;
  }
  
  .social-links {
    margin-top: 40px;
    display: flex;
    justify-content: center;
    gap: 20px;
  }
  
  .social-link {
    color: white;
    font-size: 1.5rem;
    text-decoration: none;
    transition: transform 0.3s;
  }
  
  .social-link:hover {
    transform: scale(1.2);
  }
</style>
</head>
<body>
<section class="contact" id="contact">
  <div class="contact-container">
    <h2>Get In Touch</h2>
    <p>Have a project in mind? Let's work together!</p>
    
    <form class="contact-form" action="/submit" method="POST">
      <div class="form-group">
        <label for="name">Your Name</label>
        <input 
          type="text" 
          id="name" 
          name="name" 
          required
          placeholder="John Doe">
      </div>
      
      <div class="form-group">
        <label for="email">Email Address</label>
        <input 
          type="email" 
          id="email" 
          name="email" 
          required
          placeholder="[email protected]">
      </div>
      
      <div class="form-group">
        <label for="message">Message</label>
        <textarea 
          id="message" 
          name="message" 
          required
          placeholder="Tell me about your project..."></textarea>
      </div>
      
      <button type="submit" class="submit-button">
        Send Message
      </button>
    </form>
    
    <div class="social-links">
      <a href="#" class="social-link" aria-label="LinkedIn">💼</a>
      <a href="#" class="social-link" aria-label="GitHub">🐙</a>
      <a href="#" class="social-link" aria-label="Twitter">🐦</a>
      <a href="#" class="social-link" aria-label="Email">✉️</a>
    </div>
  </div>
</section>
</body>
</html>

Replace emoji with proper icon fonts or SVG icons for a more professional appearance.

Creating a Sticky Navigation

Add smooth navigation between sections:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Portfolio with Sticky Nav</title>
<style>
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }
  
  body {
    font-family: 'Segoe UI', Tahoma, sans-serif;
  }
  
  /* Sticky Navigation */
  nav {
    position: sticky;
    top: 0;
    background: white;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    z-index: 1000;
    padding: 20px 0;
  }
  
  .nav-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  
  .logo {
    font-size: 1.5rem;
    font-weight: bold;
    color: #667eea;
  }
  
  .nav-links {
    display: flex;
    gap: 30px;
    list-style: none;
  }
  
  .nav-links a {
    text-decoration: none;
    color: #333;
    font-weight: 500;
    transition: color 0.3s;
  }
  
  .nav-links a:hover {
    color: #667eea;
  }
  
  /* Smooth scrolling */
  html {
    scroll-behavior: smooth;
  }
  
  /* Section spacing */
  section {
    min-height: 100vh;
    padding: 80px 20px;
  }
</style>
</head>
<body>
<nav>
  <div class="nav-container">
    <div class="logo">JaneSmith</div>
    <ul class="nav-links">
      <li><a href="#home">Home</a></li>
      <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>
  </div>
</nav>

<!-- Sections would go here -->
<section id="home">Hero Section</section>
<section id="about">About Section</section>
<section id="skills">Skills Section</section>
<section id="projects">Projects Section</section>
<section id="contact">Contact Section</section>
</body>
</html>

The position: sticky keeps the navigation visible as users scroll, and scroll-behavior: smooth creates smooth scrolling when clicking navigation links.

Complete Portfolio Template

Here’s a complete, ready-to-customize portfolio template:

<!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 Your Name - Web Developer">
<title>Your Name - Portfolio</title>
<style>
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }
  
  body {
    font-family: 'Segoe UI', Tahoma, sans-serif;
    line-height: 1.6;
    color: #333;
  }
  
  html {
    scroll-behavior: smooth;
  }
  
  /* Add all the CSS from previous examples here */
</style>
</head>
<body>
<!-- Navigation -->
<nav>
  <div class="nav-container">
    <div class="logo">YourName</div>
    <ul class="nav-links">
      <li><a href="#home">Home</a></li>
      <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>
  </div>
</nav>

<!-- Hero Section -->
<header class="hero" id="home">
  <h1>Your Name</h1>
  <p>Web Developer | Designer | Problem Solver</p>
  <a href="#projects" class="cta-button">View My Work</a>
</header>

<!-- About Section -->
<section class="about" id="about">
  <!-- About content from previous example -->
</section>

<!-- Skills Section -->
<section class="skills" id="skills">
  <!-- Skills grid from previous example -->
</section>

<!-- Projects Section -->
<section class="projects" id="projects">
  <!-- Project cards from previous example -->
</section>

<!-- Contact Section -->
<section class="contact" id="contact">
  <!-- Contact form from previous example -->
</section>

<!-- Footer -->
<footer style="background: #333; color: white; text-align: center; padding: 30px 20px;">
  <p>&copy; 2025 Your Name. All rights reserved.</p>
</footer>
</body>
</html>

Common Mistakes to Avoid

Mistake 1: Too Much Content Above the Fold

Problematic example: Cramming your entire life story in the hero section

Improved example: Keep the hero section concise—name, title, and one call-to-action

Why: Visitors should immediately understand who you are without scrolling through paragraphs of text.

Mistake 2: Missing Call-to-Action

Problematic example: No clear next step for visitors

Improved example: Include prominent “View My Work” or “Get In Touch” buttons

Why: Guide visitors to the most important parts of your portfolio.

Mistake 3: Poor Project Descriptions

Problematic example: “A website I made” with no other details

Improved example: Explain what the project does, technologies used, and your role

Why: Employers want to understand your technical skills and problem-solving approach.

Mistake 4: No Contact Information

Problematic example: Portfolio without any way to reach you

Improved example: Include email, contact form, or social media links

Why: The whole point is for people to contact you about opportunities!

Mistake 5: Not Mobile Responsive

Problematic example: Portfolio that looks broken on phones

Improved example: Use responsive CSS (flexbox, grid, media queries)

Why: Many recruiters will view your portfolio on mobile devices first.

Try It Yourself

Ready to build your own portfolio? Try these challenges:

Challenge 1: Basic Portfolio (Beginner)

Create a simple portfolio with:

Challenge 2: Styled Portfolio (Intermediate)

Enhance your portfolio with:

Challenge 3: Advanced Portfolio (Advanced)

Create a professional-grade portfolio featuring:

Bonus: Deploy your portfolio to a free hosting service like GitHub Pages, Netlify, or Vercel!

What You Learned

Congratulations! You now know how to:

Next Steps

Now that you can build a portfolio, explore these related tutorials:

Ready to build your portfolio? Start experimenting in our interactive HTML editor!

Back to all tutorials