6 Pure CSS1 with JSPublished 2026-10-05Free · no sign-up
Seven portfolio building blocks: a grid of projects with hover titles, a case study header with project facts, a minimal numbered index, a split intro with bio and links, a filterable grid, a featured project above smaller ones and a contact section that shows the email address.
A grid of project tiles whose titles and categories appear on hover and focus, over a darkening overlay. Each tile is a link with the project name as visible text, so the grid works fully without the hover.
The top of a case study page: client and project title, a short summary, and the project facts (role, year, services) as a description list, above a hero image. Facts as a dl keep each label paired with its value.
View code
<header class="po2"><p class="k">Case study · Linea Home</p><h3>Doubling repeat orders with a calmer checkout</h3><dl><div><dt>Role</dt><dd>Design and build</dd></div><div><dt>Year</dt><dd>2026</dd></div><div><dt>Services</dt><dd>UX, Shopify, CRO</dd></div></dl><div class="hero" aria-hidden="true"></div></header>
A text-only index of projects, each row a link with a number, name, discipline and year, a confident minimal portfolio that loads instantly. The numbers come from a CSS counter on an ordered list, and rows highlight on hover and focus.
View code
<ol class="po3"><li><a href="#p1"><b>Kiln & Co</b><span>Identity</span><time>2026</time></a></li><li><a href="#p2"><b>Tidal</b><span>Product</span><time>2025</time></a></li><li><a href="#p3"><b>Field Notes</b><span>Editorial</span><time>2025</time></a></li><li><a href="#p4"><b>Bloom</b><span>Ecommerce</span><time>2024</time></a></li></ol>
A personal portfolio opener: a big statement and short bio on one side, contact and social links on the other. The two parts sit side by side when the container is wide enough and stack otherwise, using a container query.
View code
<section class="po4"><div class="in"><div><h3>I design calm interfaces for busy people.</h3><p>Product designer in Lisbon, ten years in fintech and health.</p></div><ul><li><a href="#email">Email</a></li><li><a href="#read-cv">Read.cv</a></li><li><a href="#dribbble">Dribbble</a></li></ul></div></section>
Category buttons filter the project grid, with the active category marked by aria-pressed and a live count of how many projects are showing. Hidden projects use the hidden attribute so they leave the tab order too.
var bs = document.querySelectorAll('.po5 .f button'), lis = document.querySelectorAll('.po5 li'), n = document.querySelector('.po5 .n');
bs.forEach(function (b) { b.onclick = function () { var c = b.dataset.c, k = 0; bs.forEach(function (x) { x.setAttribute('aria-pressed', x === b); }); lis.forEach(function (li) { li.hidden = c !== 'all' && li.dataset.c !== c; if (!li.hidden) k++; }); n.textContent = 'Showing ' + k + (k === 1 ? ' project' : ' projects'); }; });
06. Featured Project Plus Grid
PortfolioLayout
One large featured project spanning the full width, followed by smaller projects in a grid, which gives a portfolio a clear lead piece. The featured tile has a short summary so it reads as the headline, not just a bigger picture.
View code
<div class="po6"><a class="lead" href="#tidal"><span class="img" aria-hidden="true"></span><span class="t"><b>Tidal</b> Banking app that halved support tickets</span></a><a href="#kiln"><span class="img" style="--g:linear-gradient(135deg,#fdba74,#c2410c)" aria-hidden="true"></span><span class="t"><b>Kiln & Co</b></span></a><a href="#bloom"><span class="img" style="--g:linear-gradient(135deg,#f9a8d4,#be185d)" aria-hidden="true"></span><span class="t"><b>Bloom</b></span></a></div>
A closing section with a big invitation, an email address as a large link and availability in plain words. The email link uses mailto and shows the address itself, which people trust more than a vague Contact me button.
View code
<section class="po7" aria-labelledby="po7h"><p class="k">Taking on projects from November</p><h3 id="po7h">Have something in mind?</h3><a href="mailto:hello@example.com">hello@example.com</a><ul><li><a href="#linkedin">LinkedIn</a></li><li><a href="#github">GitHub</a></li></ul></section>
Visitors skim the projects first. Make every tile a link with the project name in text, and save the explanation for the case study page, starting with a clear summary of the result.
Facts as data
Role, year and services are label and value pairs. A <dl> keeps them together for screen readers and is easy to lay out as a row of facts.
Filters that report back
Filter buttons should show which filter is on with aria-pressed and say how many projects are showing in a polite live region. Hidden projects need the hidden attribute so they leave the tab order.
Make contact obvious
End with a direct way to get in touch. A visible email address is clearer and more trusted than a generic Contact me button.
Frequently asked questions
Are these projects real?
No. The names are placeholders for your own work.
Should a portfolio use a lot of animation?
A little helps; heavy animation slows down people reviewing many portfolios. Let the work be the visual.
What about SEO for a portfolio?
Give each project its own page with a descriptive title and real text about the problem and result.