Your take-home test for a frontend role. Ship a responsive, accessible portfolio that passes a Lighthouse audit — the way a real hiring team will evaluate you.
This is your portfolio and your screening test simultaneously. The Lighthouse scores will be run on your actual deployed site during interviews. Polish this until all four hit 90+. It becomes the artifact you point to for the next 2 years.
At mid level, perfect Lighthouse scores are table stakes. The differentiation is architectural: why did you make specific HTML structure choices, how do you handle font loading strategy, and how would you scale this to a multi-page site with shared components.
Your take-home test for a frontend role. Ship a responsive, accessible portfolio that passes a Lighthouse audit — the way a real hiring team will evaluate you.
You receive the brief: build a portfolio page. Figma link, 48-hour deadline, Lighthouse will be run against it.
You scaffold HTML -- but you used div for everything. Lighthouse accessibility score: 43.
CRITICALSemantic HTML, alt text, ARIA landmarks added. Accessibility score: 100. Performance still 61 -- unoptimized hero image.
WARNINGImage compressed to WebP, lazy-loaded below fold, font preloaded. All four scores >= 90. Ready to submit.
The question this raises
If a machine can disqualify you before a human reads your code, what does "good HTML and CSS" actually mean in production?
A candidate submits a portfolio that looks perfect in Chrome on a 1440px monitor. Lighthouse runs and returns: Performance 94, Accessibility 67, Best Practices 92, SEO 88. What is most likely causing the accessibility score?
Lesson outline
You are applying for a frontend role. The take-home challenge is: build a personal portfolio page. No framework required. The hiring team will run Lighthouse against your deployed URL and look at your HTML source before they look at your JavaScript.
What the hiring team actually evaluates (in order)
Most rejections come from the same 4 mistakes. They are invisible in Chrome but glow in Lighthouse.
1<!-- Mistake 1: div soup — screen reader reads "generic, generic, generic" -->2<div class="header">No landmark role — nav element missing3<div class="name">Jane Smith</div>4<div class="nav">div with onclick: not keyboard accessible, no ARIA role5<div onclick="scroll('about')">About</div>6<div onclick="scroll('work')">Work</div>7</div>8</div>910<!-- Mistake 2: missing alt text — Lighthouse deducts points per image -->11<img src="hero.png">Missing alt="" — Lighthouse Accessibility -5 pts per image12<img src="project1.jpg">1314<!-- Mistake 3: render-blocking Google Fonts -->Render-blocking stylesheet — LCP penalty15<link href="https://fonts.googleapis.com/css2?family=Inter" rel="stylesheet">1617<!-- Mistake 4: fixed-pixel layout — breaks on 375px iPhone -->18<div style="width: 960px; margin: 0 auto;">
div-as-nav
<div class="nav">
<div onclick="goto('about')">About</div>
</div><nav aria-label="Main navigation">
<a href="#about">About</a>
</nav>A div with onclick is not keyboard accessible and has no semantic role. A nav with anchor tags is free keyboard navigation, ARIA landmark, and crawlable link — zero extra code.
Run Lighthouse in Chrome DevTools (Lighthouse tab → Analyze page load) before you submit. Every red item is a deduction. Here is what a failing submission looks like:
Typical failing Lighthouse report
Performance: 61 — "Properly size images" (hero.png served at 4.2MB, displayed at 600px wide) Accessibility: 43 — "Image elements do not have [alt] attributes" (6 images), "Buttons do not have an accessible name" (3 divs with onclick) Best Practices: 78 — "Serves vulnerable JavaScript libraries" (jQuery 1.6 from CDN) SEO: 52 — "Document does not have a meta description", "Links do not have descriptive text" (3x "click here")
Each item in the report links directly to the failing element and the fix. Lighthouse is not a mystery — it is a checklist with line-item feedback.
Ship a portfolio page that meets all of the following. A senior engineer will verify each item in your code review.
| Criterion | How to verify | Common failure mode |
|---|---|---|
| Single h1 with your name/title | Ctrl+F "h1" in source — should appear once | Multiple h1s, or h1 inside a div inside another div |
| nav, main, footer landmarks | Accessibility pane in DevTools → Landmarks | Using div.header, div.main, div.footer instead |
| All images have descriptive alt text | Lighthouse Accessibility audit | alt="" on meaningful images, or missing entirely |
| Fully keyboard navigable | Tab through page, no mouse | onclick on divs, missing focus styles (outline: none) |
| Mobile layout at 375px | DevTools Device toolbar → iPhone SE | Fixed-pixel widths, horizontal scroll, overlapping text |
| Lighthouse >= 90 all four scores | DevTools Lighthouse tab | Unoptimised images, render-blocking fonts, missing meta |
| No !important in CSS | Search for !important in stylesheet | Specificity wars from non-semantic class names |
The 10-minute pre-submission checklist
1. View source — count h1 (must be 1). 2. Tab through from the top — every interactive element reachable. 3. Resize to 375px — no horizontal scroll. 4. Lighthouse in incognito — all four scores on screen. 5. Grep for !important — must return 0. Ship it.
The live code review comes after the take-home. The interviewer will open your source and ask questions designed to separate people who Googled the fix from people who understand it.
Questions you will be asked — and what the strong answer sounds like
1<!-- The version that passes every check -->2<!DOCTYPE html>3<html lang="en">4<head>5<meta charset="UTF-8">6<meta name="viewport" content="width=device-width, initial-scale=1.0">7<meta name="description" content="Jane Smith — Frontend Developer based in Berlin">Meta description — required for SEO score8<title>Jane Smith | Frontend Developer</title>9<!-- Preload hero image — LCP element -->Preload hero: tells browser to fetch it immediately, improves LCP10<link rel="preload" as="image" href="hero.webp">11<!-- Self-host font or use font-display: swap to avoid render-block -->12<link rel="preconnect" href="https://fonts.googleapis.com">13</head>14<body>15<a href="#main" class="skip-link">Skip to main content</a>Skip link: keyboard users jump to content, required for a11y = 1001617<header>18<h1>Jane Smith</h1>19<nav aria-label="Main navigation">20<ul>21<li><a href="#about">About</a></li>22<li><a href="#work">Work</a></li>23<li><a href="#contact">Contact</a></li>24</ul>25</nav>26</header>2728<main id="main">29<section aria-labelledby="about-heading">30<h2 id="about-heading">About</h2>31<imgwidth + height on img: browser reserves space, eliminates CLS32src="hero.webp"33alt="Jane Smith presenting at JSConf Berlin 2023"34width="1200"35height="630"36>37</section>38</main>3940<footer>41<p><small>© 2024 Jane Smith</small></p>42</footer>43</body>44</html>
Semantic HTML
📖 What the exam expects
Using elements like nav, header, main, footer, article, section that describe the meaning of content, not just its appearance.
Toggle between what certifications teach and what production actually requires
Take-home challenges, portfolio reviews, and "walk me through a project you built" questions all land on this material. The interviewer has your source open while you talk.
Common questions:
Strong answer: Preloaded hero image. Skip link. Width/height on images. Explains the LCP strategy unprompted. Has already considered how to extend this to multiple pages.
Red flags: Lighthouse accessibility below 90. Fixed pixel layouts. Missing meta description. div soup with onclick handlers. Cannot explain a single architectural choice.
Ready to see how this works in the cloud?
Switch to Career Paths for structured paths (e.g. Developer, DevOps) and provider-specific lessons.
View role-based pathsSign in to track your progress and mark lessons complete.
Questions? Discuss in the community or start a thread below.
Join DiscordSign in to start or join a thread.