A personal portfolio website is the one project every developer and designer eventually builds, and most of them end up looking identical: a centred name, three cards, a contact form. This one is different. It uses an editorial layout with a full-bleed hero, a featured case study, and a work grid that reads like a magazine spread instead of a template.
The whole thing is HTML and CSS only. No JavaScript, no framework, no build step. Copy the two files and it runs.
What you will build
By the end you will have a complete responsive portfolio page with:
- An editorial hero with a headline that scales continuously, no breakpoints
- A featured case study panel with real outcome metrics
- A 2x2 work grid with lift-on-hover cards
- A numbered list for smaller projects
- About and contact sections
- Full responsive behaviour down to 360px
Everything below runs on two files: one HTML document and one stylesheet.
What is a portfolio website
A portfolio website is a single page that shows who you are, what you have built, and how to reach you. For developers and designers it does the job a CV cannot: it demonstrates the skill rather than describing it.
The sections that actually earn their place:
- A hero that states your discipline, not a greeting
- One featured project given real space, with outcomes
- A work grid for everything else, scannable in seconds
- A compact list for smaller engagements
- An about section with a point of view
- A contact block that says what you are available for
Step 1: Set up the design tokens
Everything on the page pulls from a small set of custom properties. Define them first and you can restyle the entire site by editing eight lines.
Two typefaces do the work. Archivo at weight 800 for headings, because it holds up at very large sizes with tight tracking, and Instrument Sans for everything else.
That letter-spacing:-.04em does more than it looks. Large display type at default tracking always reads loose, and tightening it is most of what separates a considered heading from a default one. The same trick carries the Neo Brutalism website layout, which leans even harder on oversized type.
Step 2: Build the hero

The hero is a rounded dark panel inset from the viewport edge rather than a full-bleed band. That inset is what makes the page feel designed instead of generic.
The headline uses clamp() so it scales with the viewport without a single media query:
Note the cqw unit. Because the hero declares container-type:inline-size, the heading scales against the panel's width, not the viewport's. So the type stays correct even if you later drop the hero into a narrower column.
Step 3: Lay out the featured case study

The featured project is a two-column grid: image on the left, content on the right, with the body column capped so the text never runs too wide to read.
minmax(0,1fr) on the first column matters. A plain 1fr refuses to shrink below its content's intrinsic width, which is exactly what causes grid children to overflow their container. Setting the minimum to 0 lets it actually compress.
The two metrics underneath (-38% and 6 to 1) do more work than a paragraph would. Concrete outcomes are what separate a case study from a screenshot.
Step 4: Build the work grid

Four cards in a two-column grid, each one a single anchor so the whole card is clickable:
The hover state moves three properties at once: the border darkens, a soft shadow appears, and the card lifts 3px. That negative spread on the shadow (-30px) keeps it tight under the card instead of bleeding into a grey halo. If you want a bolder take on card hovers, the responsive cards tutorial covers the same pattern with a stronger lift.
Step 5: Make it responsive
The whole page needs two breakpoints. At 980px the grids collapse to one column:
And at 620px the padding and type scale down. Because the hero heading already uses clamp() with a container query unit, it needs no adjustment at all — it has been resizing continuously the whole way down.
Two breakpoints is unusually few. Most layouts need more because they pin widths in pixels; this one uses minmax() and clamp() so the layout absorbs most of the range on its own. The responsive website layout guide works through that approach in more depth.
Design details worth copying
The inset panel. Wrapping the hero in padding:var(--pad) and rounding the corners is a small move with a large effect. It signals a designed page immediately.
One accent, used sparingly. The blue appears in the eyebrow labels, the featured badge and link hovers. The other four colours only ever appear inside project mockups. A single accent applied with restraint reads more expensive than five applied evenly.
Numbered structure. Section eyebrows read 01 / SELECTED WORK, and the smaller projects list is numbered 06 to 09, continuing from the four cards above. The numbering encodes something true about the content rather than decorating it.
Generous line height on body copy, tight on headings. Body text sits at 1.6, headings at 1. That contrast is what makes a page feel edited.
Where to go next
Once this is running, the natural additions are a collapsible sidebar if you expand into a multi-page site, or a bento grid section to show more projects in less vertical space.
If you want to see the same editorial approach applied to a full marketing site rather than a portfolio, building a responsive website with HTML and CSS covers that layout end to end.
Frequently Asked Questions
Do I need JavaScript for this portfolio website?
No. Everything here is HTML and CSS, including the hover states and the responsive behaviour. You would only add JavaScript for a mobile menu toggle, a theme switch, or a working contact form.
How do I add my own project images?
Each card has a .shot container. Replace its contents with an <img> and add object-fit:cover so your screenshot fills the frame at any aspect ratio:
What is cqw and do I need it?
cqw is a container query unit: 1cqw is 1% of the nearest container's width, and it needs container-type:inline-size on the parent. You do not strictly need it — vw works too — but cqw means the type scales with the panel rather than the window.
How do I change the colours?
Edit the custom properties in :root. Every colour on the page references one of them, so changing --blue restyles every accent at once.
Is this portfolio website responsive?
Yes. It collapses to a single column at 980px and tightens spacing at 620px. The hero headline scales continuously with clamp(), so there is no jump between breakpoints.
Can I use this portfolio template for free?
Yes. The complete source code is in the preview above. Copy it, change the content and colours, and use it for personal or client work.

