Free Portfolio Website Template (HTML & CSS, 2026)
A clean, responsive, accessible personal portfolio template in plain HTML and CSS — hero, projects grid, about and contact sections — ready to copy, customize and deploy.
This is a free, responsive portfolio website template built with plain HTML and modern CSS — no framework, no build step. It has a hero, a projects grid, an about section and a contact call-to-action, uses CSS custom properties so you can restyle it in seconds, and is accessible and mobile-first out of the box. Copy it, make it yours, and deploy.
What you get
- A semantic, accessible single-page layout (header, hero, projects, about, contact, footer).
- A responsive projects grid that reflows with no media queries (
auto-fit+minmax). - Fluid typography with
clamp()and a tidy dark theme via CSS custom properties. - Zero dependencies — just two files, works anywhere.
The HTML
Save this as index.html. It’s semantic and screen-reader friendly — one <h1>, labelled navigation, and real landmark elements.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Jane Doe — Frontend Developer</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#top" class="logo">Jane Doe</a>
<nav aria-label="Primary">
<a href="#projects">Projects</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>
</nav>
</header>
<main id="top">
<section class="hero">
<p class="eyebrow">Frontend Developer</p>
<h1>I build fast, accessible web experiences.</h1>
<p class="lede">I'm Jane, a developer specializing in React, TypeScript and
modern CSS. I turn ideas into polished, performant products.</p>
<div class="actions">
<a class="btn btn-primary" href="#projects">View my work</a>
<a class="btn btn-ghost" href="#contact">Get in touch</a>
</div>
</section>
<section id="projects" class="section">
<h2>Selected work</h2>
<div class="grid">
<article class="card">
<h3>Project One</h3>
<p>What you built, the problem it solved, and the stack you used.</p>
<a href="#">View project →</a>
</article>
<article class="card">
<h3>Project Two</h3>
<p>Keep each description to two short, concrete sentences.</p>
<a href="#">View project →</a>
</article>
<article class="card">
<h3>Project Three</h3>
<p>Lead with impact: what changed because this exists.</p>
<a href="#">View project →</a>
</article>
</div>
</section>
<section id="about" class="section">
<h2>About me</h2>
<p class="prose">A short paragraph about who you are, what you love building,
and what you're looking for. Keep it human and specific.</p>
</section>
<section id="contact" class="section">
<h2>Let's work together</h2>
<p class="prose">Open to freelance and full-time roles. The fastest way to
reach me is email.</p>
<a class="btn btn-primary" href="mailto:[email protected]">Email me</a>
</section>
</main>
<footer class="site-footer">
<p>© 2026 Jane Doe.</p>
</footer>
</body>
</html>
The CSS
Save this as styles.css. The design tokens live at the top — edit --accent and --bg and the whole site follows.
:root {
--bg: #0b0d14;
--surface: #141824;
--text: #e8ecf4;
--muted: #9aa4b8;
--accent: #6ea8ff;
--border: #232838;
--radius: 14px;
--max: 960px;
color-scheme: dark;
}
* { box-sizing: border-box; margin: 0; }
body {
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
background: var(--bg); color: var(--text); line-height: 1.6;
}
a { color: var(--accent); }
.site-header, main, .site-footer { max-width: var(--max); margin-inline: auto; padding: 20px; }
.site-header { display: flex; justify-content: space-between; align-items: center; }
.site-header nav { display: flex; gap: 22px; }
.site-header nav a { color: var(--muted); text-decoration: none; }
.site-header nav a:hover { color: var(--text); }
.logo { font-weight: 700; color: var(--text); text-decoration: none; }
.hero { padding: 72px 0; }
.eyebrow { color: var(--accent); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; font-size: 14px; }
h1 { font-size: clamp(32px, 6vw, 56px); line-height: 1.1; margin: 12px 0 16px; letter-spacing: -.02em; }
.lede { color: var(--muted); font-size: clamp(17px, 2.5vw, 20px); max-width: 46ch; }
.actions { display: flex; gap: 14px; margin-top: 28px; flex-wrap: wrap; }
.btn { display: inline-block; padding: 12px 22px; border-radius: 10px; font-weight: 600; text-decoration: none; }
.btn-primary { background: var(--accent); color: #06080f; }
.btn-ghost { border: 1px solid var(--border); color: var(--text); }
.btn:hover { filter: brightness(1.08); }
.section { padding: 56px 0; border-top: 1px solid var(--border); }
h2 { font-size: clamp(24px, 4vw, 34px); margin-bottom: 28px; letter-spacing: -.01em; }
.prose { color: var(--muted); max-width: 60ch; margin-bottom: 20px; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px; }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 24px; }
.card h3 { margin-bottom: 8px; }
.card p { color: var(--muted); margin-bottom: 14px; }
.card a { text-decoration: none; }
.site-footer { color: var(--muted); border-top: 1px solid var(--border); }
@media (max-width: 560px) {
.site-header { flex-direction: column; gap: 10px; align-items: flex-start; }
}
How to customize
- Colors: change
--accent,--bg,--surfaceand--textin:root. For a light theme, flip--bg/--textand setcolor-scheme: light. - Content: replace the name, hero copy, and the three project cards. Add more cards — the grid reflows automatically.
- Sections: duplicate a
<section class="section">to add experience, skills or testimonials. - Fonts: the system font stack is fast and free; to use a web font, add a
@font-faceand set it onbody(see how to optimize CSS).
Deploy it
It’s two static files, so hosting is free and instant on Netlify, Vercel, Cloudflare Pages or GitHub Pages — drag the folder in, or connect a repo. Because there’s no build step, there’s nothing to configure.
Frequently asked questions
Is this portfolio template free to use?
How do I make the portfolio template light instead of dark?
:root: set --bg to a light color (e.g. #ffffff), --surface to a light grey, --text to a dark color, and change color-scheme: dark to light. Because every color references a variable, the whole site switches theme from those few edits.Do I need a framework or build tools?
How do I add more projects?
<article class="card"> blocks inside the projects grid and change its content. The grid uses repeat(auto-fit, minmax(240px, 1fr)), so it automatically arranges any number of cards into a responsive layout with no extra CSS.Open this template in XCODX Studio to edit and preview it live in your browser — then deploy. See also the landing page template, resume website template and our CSS best practices.