This is a living document — updated as often as possible to keep the helps, references, and resources below current and relevant.
A reference for building on the web platform itself — HTML, CSS, JavaScript, and Web Components as browsers actually implement them, plus the media, performance, accessibility, PWA, and testing practices that go with them — with no UI frameworks layered on top. Each topic below is a short pointer to the best resource I've found on it, not a full explanation in itself.
Picking the right element (<article>, <nav>, <section>, <aside>...) instead of a generic <div> for everything gives structure meaning to browsers, screen readers, and search engines.
- Periodic Table of HTML Elements — all 115 elements laid out by category, great for spotting ones you've forgotten exist
- HTML elements reference (MDN)
- Semantic HTML (web.dev)
What belongs in <head> — title, charset, viewport, favicons, and the meta tags that control how a page is described and shared.
- What's in the head? Web page metadata (MDN)
- HEAD — a simple guide to HTML
<head>elements - Metadata (web.dev)
Native HTML can validate a lot of form input on its own — required, pattern, type="email" — before you'd reach for JavaScript.
Kevin Powell is worth a general mention here — a genuine expert on all things CSS, and a great resource beyond any single topic below.
The full set of CSS rules and properties as browsers implement them, not tied to any one topic below.
- CSS Sky — a fantastic CSS reference, presented as an animated galaxy that's just as fun to explore as it is useful
- CSS reference (MDN)
- Learn CSS (web.dev)
Why one rule beats another when two selectors target the same element — the ID/class/type weighting system that decides it.
Content, padding, border, margin — and why box-sizing: border-box fixes most of the confusion around element sizing.
One-dimensional layout — a single row or column — for distributing and aligning items within a container.
Two-dimensional layout — rows and columns together — for page-level and component-level layouts that flexbox isn't suited for.
Native CSS variables (--my-color) for values you reuse, and @layer for controlling which groups of rules win without fighting specificity.
Building layouts that adapt to viewport size without a framework's grid system doing it for you.
The parts of native JS that feel like magic until they click — where a variable is visible from, why an inner function can still see an outer function's variables after it has returned, and what this is bound to depending on how a function is called.
Selecting, creating, and modifying elements directly with querySelector, createElement, and friends — no jQuery required.
Listening and reacting to what happens on a page — clicks, input, keypresses — with addEventListener.
Handling things that don't finish immediately — fetch requests, timers — without nesting callbacks.
Splitting code across files with native import/export — no bundler required for the browser to understand it.
Defining your own HTML tags (class MyWidget extends HTMLElement) with their own behavior, registered with customElements.define().
Attaching an encapsulated DOM subtree to an element, with its own scoped styles that don't leak in or out of the rest of the page.
<template> for declaring inert, reusable markup that isn't rendered until cloned into the DOM, and <slot> for composing content passed into a custom element.
Serving the right image — size, resolution, even a different crop — for the viewport and device requesting it, with srcset, sizes, and <picture>.
Modern compressed formats like WebP and AVIF beat JPEG/PNG on file size, and the native loading="lazy" attribute defers offscreen images without a library.
The <video> and <audio> elements, <source> for format fallbacks, and <track> for captions/subtitles — no video.js or other player library required.
How the browser goes from HTML/CSS/JS to pixels on screen, and what blocks it along the way — the foundation for most other performance work.
Giving the browser a head start with preconnect, preload, and prefetch — without a bundler or framework doing it automatically.
Fonts are often the biggest render-blocking resource on a page — font-display, self-hosting, and subsetting fix most of it.
Loading only the JavaScript a page actually needs upfront, using native dynamic import().
The three field metrics — LCP, INP, CLS — Google uses to measure real-world loading speed, responsiveness, and visual stability.
The first rule of ARIA is not to use it — reach for the right native element before reaching for ARIA attributes on a <div>.
Making sure everything reachable with a mouse is also reachable — and visibly focused — with just a keyboard.
Meeting WCAG contrast ratios, and respecting prefers-color-scheme/prefers-contrast for users with low vision or color blindness.
Labels, descriptions, and error messages connected to their fields programmatically, not just visually.
manifest.json — the name, icons, theme color, and display mode that let a browser treat a site as an installable app.
A script that sits between the page and the network, intercepting requests to serve cached responses — the basis of offline support.
What makes a site eligible to be installed, and the beforeinstallprompt event for offering your own install UI.
Re-engaging users outside the browser tab with the Push API and Notifications API.
Fast, isolated tests for individual functions and modules, run without a browser.
Simulating real user flows in a real browser — clicking, typing, navigating — to catch what unit tests can't.
Automated checks that catch a subset of accessibility issues, worth running as part of a test suite — but no substitute for manual and assistive-tech testing.
A running, personal collection of the tools, references, and people I follow for front-end work — kept separately and updated over time.