Capstone: An Accessible, Fast, Findable Website

The final build. Everything in the path applied to one real site, with a defined standard it has to meet before it is finished.

The brief

Build a complete website of at least eight pages that meets a stated standard on accessibility, performance and search. This is the project to put in front of an employer.

Choose a subject you actually know something about - a local organisation, a hobby, a small business, a subject you can write about. Real content is what makes the difference between a template and a portfolio piece.

The standard

The site is finished when all of this is true. Not before.

Markup

  • Every page validates with zero errors.
  • Semantic elements throughout; no clickable div anywhere.
  • One h1 per page, no skipped heading levels.
  • Landmarks on every page, every nav labelled.
  • A shared layout, so a fix lands everywhere at once.

Accessibility

  • An automated scan reports zero violations on every page.
  • Every page fully operable with the keyboard.
  • Visible focus indicator at 3 to 1 contrast, never obscured.
  • A working skip link on every page.
  • Body text at 4.5 to 1 contrast, large text at 3 to 1.
  • No information conveyed by colour alone.
  • prefers-reduced-motion honoured.
  • All forms labelled, grouped and with an accessible error pattern.
  • Usable at 200 percent zoom.
  • Tested with a screen reader on at least three pages.

Performance

  • Largest Contentful Paint under 2.5 seconds on a throttled connection.
  • Cumulative Layout Shift under 0.1.
  • Every image and iframe has dimensions.
  • Responsive images with srcset and sizes.
  • Modern image formats with fallbacks.
  • Below the fold content lazy loaded; the hero is not.
  • Every script deferred.
  • Total page weight under about 500 KB on a content page.
  • Unique title and description on every page.
  • Self referencing absolute canonical on every page.
  • An accurate XML sitemap, referenced from robots.txt.
  • No stray noindex; robots.txt does not block anything it should not.
  • Open Graph tags with a correctly sized image.
  • Structured data appropriate to each page type, validating.
  • Breadcrumbs on deep pages, with markup.
  • No orphan pages; nothing more than three clicks from home.

Robustness

  • HTTPS, with HTTP redirecting.
  • The core content works with JavaScript disabled.
  • A real 404 page returning a 404 status.
  • No console errors in production.
  • Tested in at least two browsers and on a real phone.

A suggested structure

/                      home
/about                 about the organisation
/services              or /work, or /courses
/services/[one]        one item in detail
/journal               an article index
/journal/[article]     one full article
/contact               address, hours, form
/404                   not found

/sitemap.xml
/robots.txt

Eight pages covering five different page types, which is what makes it a portfolio piece rather than eight copies of one layout.

A build order that works

1. Content first

Write the actual words before opening an editor. Real content changes every layout decision, and lorem ipsum hides every problem that matters - long headings, awkward names, a paragraph that will not fit.

2. Markup with no styling

Build every page as an unstyled document. Read each one top to bottom. If it makes sense as plain text, the structure is right.

3. Base styles

Typography, colours, spacing scale, focus styles, the reduced motion block. Set the tokens once.

:root {
  --text: #1e293b;
  --muted: #475569;
  --accent: #1e3a8a;
  --bg: #ffffff;
  --line: #cbd5e1;
  --space: 1rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --text: #e2e8f0;
    --muted: #94a3b8;
    --accent: #93c5fd;
    --bg: #0f172a;
    --line: #334155;
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

4. Layout

Grid and flexbox. Mobile first, adding complexity with min-width queries. Keep source order equal to reading order.

5. Enhancement

Add JavaScript only where it improves something that already works: a mobile menu, a filter, a form that submits without a reload.

6. Metadata and structured data

Titles, descriptions, canonicals, Open Graph, JSON-LD. Generate them from the same data that renders the page.

7. Measure and fix

Validate, scan, tab through, run Lighthouse, throttle, test on a phone. Fix what each one finds.

The final audit

// run on every page before calling it finished
const ids = $$("[id]").map(el => el.id);
console.log("duplicate ids:", ids.filter((id, i) => ids.indexOf(id) !== i));
console.log("no alt:", $$("img:not([alt])"));
console.log("no dimensions:", $$("img:not([width]), img:not([height])"));
console.log("untitled iframes:", $$("iframe:not([title])"));
console.log("weak links:", $$("a").filter(a =>
  /^(click here|read more|link|here|more)$/i.test(a.textContent.trim())));
console.log("missing rel:", $$("a[target='_blank']:not([rel*='noopener'])"));
console.log("no name:", $$("input, select, textarea").filter(el => !el.name));
console.table($$("h1,h2,h3,h4,h5,h6").map(h => ({ level: h.tagName, text: h.textContent.trim() })));

Then the manual pass: keyboard, images off, 320 pixels, 200 percent zoom, screen reader, throttled connection.

What to write up

A short document alongside the site, covering:

  • What it is and who it is for.
  • Three decisions you made and why - an element choice, a layout choice, a performance choice.
  • The measurements: Lighthouse scores, page weight, validation results, accessibility scan results.
  • What you would do next with more time.

The write up is what turns a built site into evidence that you know what you were doing. Anyone can produce a page that looks acceptable; being able to explain why each decision was made is the difference.

Common ways this project goes wrong

  • Styling before structure. The markup ends up serving the design instead of the content.
  • Lorem ipsum. Every layout works with placeholder text and breaks with real headings.
  • One page built well and seven copied badly. Use a shared layout.
  • Accessibility left until the end. By then it means rewriting.
  • Measuring on a fast connection. Throttle, always.
  • Not testing on a real phone.
  • Deploying without checking robots.txt and the robots meta tag in production.

Practice

  1. Write the content for eight pages before opening an editor.
  2. Build every page unstyled and read each one as plain text.
  3. Meet every item in the standard above, and record the measurements.
  4. Write the accompanying document explaining three decisions.
  5. Deploy it, verify production, and put the URL on your resume.

Useful resources

Hand picked references for this topic
Written by Lorens Mishra

Default administrator account created by the installer.

Continue reading

All HTML notes →

Discussion

0 comments
Sign in to join the discussion.

No comments yet. Be the first to say something.