Project: Build a Personal Portfolio Website using Flexbox
Step-by-step project guide. Learn how to build a responsive personal developer portfolio website using HTML and CSS Flexbox.
Introduction
The best way to solidify your CSS knowledge is to build projects. In this first capstone project, you will build a Personal Portfolio Website from scratch.
A portfolio is the most critical asset for a frontend developer. It showcases your skills, hosts links to your work, and serves as your visual resume for placements. In this project, we will use semantic HTML5 structure, clean custom variables, and Flexbox for alignments, creating a responsive, premium layout that looks polished on both mobile and desktop.
What You Will Learn
- Building a semantic HTML5 page structure.
- Creating a responsive navbar that collapses on mobile.
- Centering and aligning text blocks inside a hero banner.
- Aligning a grid of project cards using Flexbox wrapping.
- Customizing form input styles for a contact form.
Prerequisites
- CSS Flexbox Item Sizing: Flex Grow, Flex Shrink, and Flex Basis
- Borders and Outlines: Radii, Styles, and Visual Offsets
Project Specifications
Color Theme:
- Background: Dark slate (
#0f172a) - Card backgrounds: Slate (
#1e293b) - Primary Accent: Indigo (
#6366f1) - Text: White (
#ffffff) and gray (#94a3b8)
Typography:
- Headings: Sans-serif (Inter/Outfit)
- Body: Sans-serif
Step 1: The HTML5 Document Structure
Create an index.html file and lay out the semantic blocks:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Developer Portfolio</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Navigation Bar -->
<header class="navbar">
<div class="logo">DevPortfolio</div>
<nav class="nav-links">
<a href="#about">About</a>
<a href="#projects">Projects</a>
<a href="#contact">Contact</a>
</nav>
</header>
<!-- Hero Section -->
<section id="about" class="hero">
<div class="hero-content">
<h1>Hi, I'm <span class="accent">Alex</span></h1>
<p>Frontend Engineer specializing in premium web experiences.</p>
<a href="#contact" class="btn-primary">Get In Touch</a>
</div>
</section>
<!-- Projects Section -->
<section id="projects" class="projects">
<h2>My Projects</h2>
<div class="projects-grid">
<!-- Card 1 -->
<div class="project-card">
<h3>E-Commerce Interface</h3>
<p>A responsive online store interface built with HTML5 and Flexbox layout rules.</p>
<a href="#" class="project-link">View Project →</a>
</div>
<!-- Card 2 -->
<div class="project-card">
<h3>Dashboard Console</h3>
<p>A dark-mode analytics console showcasing visual tables and custom scrollbars.</p>
<a href="#" class="project-link">View Project →</a>
</div>
</div>
</section>
<!-- Contact Section -->
<section id="contact" class="contact">
<h2>Contact Me</h2>
<form class="contact-form">
<input type="text" placeholder="Name" required>
<input type="email" placeholder="Email" required>
<textarea placeholder="Message" rows="5" required></textarea>
<button type="submit" class="btn-primary">Send Message</button>
</form>
</section>
</body>
</html>
Step 2: The CSS Stylesheet (style.css)
Create a style.css file. We will define custom variables and use Flexbox to lay out the sections:
/* ==========================================================================
Base Resets & CSS Variables
========================================================================== */
:root {
--bg-dark: #0f172a;
--bg-card: #1e293b;
--color-primary: #6366f1;
--color-primary-hover: #4f46e5;
--text-white: #ffffff;
--text-gray: #94a3b8;
--font-sans: 'Inter', system-ui, -apple-system, sans-serif;
}
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
scroll-behavior: smooth;
}
body {
background-color: var(--bg-dark);
color: var(--text-white);
font-family: var(--font-sans);
line-height: 1.6;
}
/* ==========================================================================
Navigation Bar (Flexbox)
========================================================================== */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 40px;
background-color: rgba(15, 23, 42, 0.9);
backdrop-filter: blur(12px);
position: sticky;
top: 0;
z-index: 100;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.logo {
font-size: 1.5rem;
font-weight: 700;
color: var(--color-primary);
}
.nav-links a {
color: var(--text-gray);
text-decoration: none;
margin-left: 24px;
font-weight: 500;
transition: color 0.2s ease;
}
.nav-links a:hover {
color: var(--text-white);
}
/* ==========================================================================
Hero Section (Flexbox Centering)
========================================================================== */
.hero {
min-height: 90vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
padding: 40px 20px;
}
.hero-content h1 {
font-size: 3.5rem;
font-weight: 800;
margin-bottom: 16px;
}
.hero-content .accent {
color: var(--color-primary);
}
.hero-content p {
font-size: 1.25rem;
color: var(--text-gray);
max-width: 600px;
margin: 0 auto 32px auto;
}
.btn-primary {
display: inline-block;
background-color: var(--color-primary);
color: var(--text-white);
padding: 12px 28px;
border-radius: 8px;
text-decoration: none;
font-weight: 600;
border: none;
cursor: pointer;
transition: background-color 0.2s ease, transform 0.2s ease;
}
.btn-primary:hover {
background-color: var(--color-primary-hover);
transform: translateY(-2px);
}
/* ==========================================================================
Projects Section (Flexbox wrapping)
========================================================================== */
.projects {
padding: 80px 40px;
max-width: 1200px;
margin: 0 auto;
}
.projects h2 {
font-size: 2.25rem;
margin-bottom: 40px;
text-align: center;
}
.projects-grid {
display: flex;
flex-wrap: wrap; /* Wraps cards on mobile viewports */
gap: 24px;
}
.project-card {
background-color: var(--bg-card);
border: 1px solid rgba(255, 255, 255, 0.05);
padding: 32px;
border-radius: 12px;
/* Flexbox parameters for cards: grow, shrink, default basis width */
flex: 1 1 350px;
transition: transform 0.3s ease, border-color 0.3s ease;
}
.project-card:hover {
transform: translateY(-5px);
border-color: var(--color-primary);
}
.project-card h3 {
font-size: 1.5rem;
margin-bottom: 12px;
}
.project-card p {
color: var(--text-gray);
margin-bottom: 24px;
}
.project-link {
color: var(--color-primary);
text-decoration: none;
font-weight: 600;
}
/* ==========================================================================
Contact Section
========================================================================== */
.contact {
padding: 80px 40px;
max-width: 600px;
margin: 0 auto;
}
.contact h2 {
font-size: 2.25rem;
margin-bottom: 40px;
text-align: center;
}
.contact-form {
display: flex;
flex-direction: column; /* Vertical stack inputs */
gap: 16px;
}
.contact-form input,
.contact-form textarea {
background-color: var(--bg-card);
border: 1px solid rgba(255, 255, 255, 0.1);
padding: 16px;
border-radius: 8px;
color: var(--text-white);
font-family: inherit;
}
.contact-form input:focus,
.contact-form textarea:focus {
outline: 2px solid var(--color-primary);
}
Visual Learning Diagram (Mermaid)
graph TD
subgraph Mobile-First Portfolio Structure
Nav[Navbar: flex row / wrap-on-mobile]
Hero[Hero Section: flex justify-center, align-center]
Grid[Projects Grid: flex wrap / flex: 1 1 350px]
Form[Contact Form: flex column / vertical stack]
end
Responsive Adjustments: Mobile Media Query
Add a media query at the bottom of style.css to adjust padding and layouts on mobile screens under 768px:
@media (max-width: 768px) {
.navbar {
flex-direction: column; /* Stack logo and links vertically */
gap: 12px;
padding: 16px;
}
.nav-links a {
margin: 0 10px;
}
.hero-content h1 {
font-size: 2.5rem; /* Scale headings down */
}
.projects, .contact {
padding: 60px 20px;
}
}
Summary
This Personal Portfolio Website uses semantic HTML5 structured wrappers styled using custom CSS variables. Navigation lists, hero blocks, projects grids, and contact inputs are aligned responsively utilizing Flexbox rows, wraps, columns, and mobile media queries.
Related Articles
Next Tutorial
Ready for a more advanced layout? Let's build a SaaS product landing page using CSS Grid: Project: SaaS Landing Page.