Web development project ideas: 13 builds for HTML, CSS and the browser
Good web development projects teach the parts of the platform that frameworks hide: layout with CSS grid and container queries, forms that validate natively, accessible components, responsive images, print styles and offline support. Rebuild a real landing page, build a pricing page, a dark mode with design tokens, an invoice that prints well, or an installable offline app. Below are 13 projects in three groups, each with a stack, a first version, a stretch goal and a time estimate.
What should a web development project teach?
The web platform itself. Most course projects are a framework tutorial with a different logo. These projects are the opposite: they use plain HTML, CSS and a little JavaScript, so you learn what the browser does before a library does it for you. That knowledge carries into every framework you pick up later.
The 13 projects are grouped by area, not by difficulty, because a web developer needs all three: layout and style, forms and accessibility, and performance and the platform. Each can be built without a build step. For projects that are mostly JavaScript logic, see JavaScript project ideas. For projects with a server and a database, see full stack project ideas.
| Your goal | Start with | Why |
|---|---|---|
| Get hired for front-end work | Landing page rebuild, then the accessibility fix-up | Employers look at fidelity and at keyboard use |
| Learn modern CSS | Pricing page, dark mode tokens | Grid, container queries, custom properties |
| Build for clients | HTML email, print invoice | The unglamorous work people pay for |
| Make fast sites | Performance-budget page, image gallery | You get numbers to report |
| Build app-like sites | Installable offline app, web component | Service workers and custom elements |
Which layout and CSS projects are worth building?
These four make you write a lot of CSS and read the result in a browser. Resize the window as you go. A layout you have only seen at one width is not a layout yet.
01 Rebuild a real landing page from a screenshot
Take a screenshot of a landing page you admire and recreate it in plain HTML and CSS at three widths.
- Stack
- HTML, CSS. No framework.
- Teaches
- Reading a design, spacing scales, flexbox and grid, fluid type, semantic elements.
- First version
- Header, hero, three feature blocks, a footer, matched at 390, 768 and 1280 pixel widths.
- Stretch goal
- Overlay your page on the screenshot at 50 percent opacity and fix every difference over 2 pixels. Then replace fixed breakpoints with clamp() sizes.
- Time
- 6 to 10 hours.
Choose a page with simple content and strong typography, not a page full of animation. Write down the spacing values you measure, such as 8, 16, 24, 48, and reuse only those. Use real heading levels and a single main element. You will be surprised how much of “design” is a short list of repeated numbers.
02 Pricing page with container queries
Three plan cards and a comparison table that change layout by the space they have, not by the screen width.
- Stack
- HTML, CSS grid, container queries.
- Teaches
- Grid, auto-fit and minmax, container queries, a table that survives narrow screens.
- First version
- Cards sit in a row when the container is wider than 720 pixels and stack below that. The comparison table scrolls sideways inside its own wrapper.
- Stretch goal
- A monthly or yearly toggle that works with no JavaScript, built from radio inputs and the :has() selector, and a highlighted plan.
- Time
- 5 to 8 hours.
Put the same card component in a narrow sidebar and in a wide main column on a test page. If it adapts in both, your container queries work. Check support for any newer selector on MDN before you rely on it, and provide a sensible layout where it is missing.
03 Dark mode with design tokens
A small site whose colors, spacing and type come from CSS custom properties, with automatic dark mode and a manual toggle.
- Stack
- HTML, CSS custom properties, a few lines of JavaScript.
- Teaches
- prefers-color-scheme, the color-scheme property, token naming, contrast.
- First version
- Tokens for background, text, border and accent in one :root block. A dark set under the media query. Contrast of every pair checked to at least 4.5 to 1.
- Stretch goal
- A three-way toggle (system, light, dark) that remembers the choice in Web Storage and never flashes the wrong theme on load.
- Time
- 4 to 7 hours.
The flash happens because the theme is set after the page paints. Set the attribute with a tiny inline script in the head, before the body renders. Name tokens by role, such as surface and text-muted, not by value, such as gray-200, so a dark set can change the values without renaming. The board's palette from a photo, contrast already checked is a bigger version of the contrast step.
04 Invoice page that prints properly
An invoice built in HTML that prints to A4 or Letter with the right page breaks, headers and no screen-only parts.
- Stack
- HTML, CSS with a print stylesheet, a little JavaScript for line totals.
- Teaches
- Print media styles, the @page rule, break-inside, tables, tabular numbers.
- First version
- Editable line items with quantity, unit price and total. Buttons and borders disappear when printing. Save as PDF gives one clean page.
- Stretch goal
- A 60-line invoice that spans two pages, repeats the table header on page two and never splits a row.
- Time
- 5 to 8 hours.
Test in the browser’s print preview, not on screen. Keep money in whole cents internally and format it for display. Use a font setting for numbers that gives every digit the same width, so columns line up.
Which forms and accessibility projects should I build?
Forms and accessibility are where client work actually fails. Many people can make a page look right. Fewer can make it work with a keyboard, a screen reader and a flaky connection.
01 A deliberately broken page, then fixed
Build a page with ten accessibility faults on purpose, then find and fix each one using only a keyboard and free checkers.
- Stack
- HTML, CSS.
- Teaches
- Semantic elements, labels, focus order, visible focus, contrast, alt text, WCAG 2.2.
- First version
- A page with a div-based button, an unlabeled input, low-contrast text, a missing alt, a focus ring removed and a modal that traps nothing. Then a commit that fixes each, with a note naming the WCAG criterion.
- Stretch goal
- Add a test that runs an accessibility checker in CI and fails on new violations.
- Time
- 6 to 10 hours.
A worked number: the gray #777777 on a white background has a contrast ratio of about 4.48 to 1 and just fails AA for body text, while #767676 passes. Learn to check this with a contrast checker, then learn what the checker cannot see, such as a link that says “click here”. WCAG 2.2 also asks for pointer targets of at least 24 by 24 CSS pixels at level AA, which is quick to check.
02 Checkout form that validates natively
A shipping and payment-style form that uses the browser’s own validation first and adds clear, inline messages.
- Stack
- HTML, CSS, a few lines of JavaScript.
- Teaches
- Input types, pattern, autocomplete tokens, Constraint Validation, setCustomValidity, error text tied to fields.
- First version
- Required fields, type=email and tel, correct autocomplete values, and error messages that appear beside each field when it is left.
- Stretch goal
- A postcode rule that depends on the selected country, and errors announced to a screen reader without moving focus.
- Time
- 5 to 8 hours.
Do not collect real card numbers. Stop at a form that would hand its data to a payment provider. The lesson is the quality of the form: labels you can click, the right mobile keyboard for each field, and messages that say what to fix rather than “invalid input”.
03 A filter that works with JavaScript turned off
A list of 100 items with a filter form that works as a plain page load first, then upgrades to instant filtering when scripts run.
- Stack
- HTML forms, a tiny server or a static page per filter, a little JavaScript.
- Teaches
- Progressive enhancement, GET forms, links as state, the History API.
- First version
- A form with method=get that reloads with ?type=... and shows the matching items. Every filtered view has a real URL.
- Stretch goal
- A script that intercepts the form, fetches the new list and swaps it in, without breaking the back button.
- Time
- 6 to 10 hours.
Build the no-script version first and make sure it is complete. The enhanced version is then a speed-up, not a requirement. This is the habit that keeps a site usable when a script fails to load, which on mobile networks it sometimes does.
04 HTML email template
A newsletter or receipt email that looks right in the big mail clients, built the old way with tables and inline styles.
- Stack
- HTML tables, inline CSS, Can I email.
- Teaches
- Why email is not the web, defensive CSS, fallback fonts, dark-mode behavior, plain-text parts.
- First version
- A single column at 600 pixels wide with a logo, a headline, a button, a footer and an unsubscribe line. Checked against a list of clients.
- Stretch goal
- A two-column layout that stacks on phones, an image with a background color that works when images are blocked, and a plain-text version.
- Time
- 6 to 10 hours.
Email clients support different slices of CSS, and Can I email tracks which. Look up each property you use and keep the layout working when a property is ignored. Send tests only to addresses you own. Never send test messages to a list of real people.
Which performance and platform projects teach the most?
The last group gives you numbers you can quote: seconds saved, kilobytes cut, a score before and after. It also covers browser features that turn a page into something closer to an app.
01 Landing page with a performance budget
A marketing page that meets a written budget, and a before-and-after report showing how you got there.
- Stack
- HTML, CSS, no framework; Lighthouse and the browser’s performance panel.
- Teaches
- Core Web Vitals, render-blocking resources, font loading, image sizing, measuring.
- First version
- Budget: LCP under 2.5 seconds, CLS under 0.1, under 150 kilobytes of transferred files. Measure a slow 4G profile, fix, measure again.
- Stretch goal
- Add a check that fails the build when a file grows past the budget.
- Time
- 6 to 10 hours.
Start by making it slow on purpose: a 3 megabyte hero image, three web fonts, a script in the head. Record the numbers. Then fix one thing at a time and record again. The table of what each change saved is the real deliverable.
02 Responsive image gallery
A grid of photos that loads small images on small screens, lazy-loads those below the fold and never shifts the page while loading.
- Stack
- HTML, CSS, responsive images.
- Teaches
- srcset and sizes, picture and modern formats, loading=lazy, width and height attributes, aspect-ratio.
- First version
- 20 photos each exported at 480, 960 and 1440 pixels wide, with sizes="(min-width: 900px) 33vw, 100vw". The page layout never jumps.
- Stretch goal
- A lightbox built on the dialog element, with keyboard navigation and focus returning to the thumbnail.
- Time
- 5 to 8 hours.
Open the network panel on a phone-sized window and confirm the browser picked the 480 pixel file. Add width and height to every image so the browser reserves the space before the file arrives. That one change usually fixes layout shift on gallery pages.
03 Installable offline recipe viewer
A small site you can add to your home screen, that opens and works with no connection after the first visit.
- Stack
- HTML, CSS, a web app manifest, a service worker.
- Teaches
- The Cache API, caching strategies, install and activate events, update flow.
- First version
- 20 recipes as static pages. The service worker caches the shell and each recipe the first time it is opened. Airplane mode still works.
- Stretch goal
- Show a “new version available” bar when the worker updates, and store a shopping list in IndexedDB.
- Time
- 8 to 12 hours.
Service workers are hard to debug because they outlive your edits. Learn the browser’s Application panel and how to unregister a worker. Read the MDN guide to progressive web apps for the install requirements, since they differ by browser.
04 Star-rating web component
A custom element, <star-rating>, with Shadow DOM, keyboard support and a value that submits with its form.
- Stack
- Plain JavaScript, web components.
- Teaches
- Custom elements, Shadow DOM, attributes versus properties, ElementInternals for form participation.
- First version
- <star-rating value="3" max="5"> renders stars, changes with click and arrow keys, and fires a change event.
- Stretch goal
- Make it form-associated so the value is submitted with the form, and expose its colors as CSS custom properties.
- Time
- 6 to 10 hours.
Give the element a role of slider or use a radio group inside, so assistive tools understand it. Test it in a page that uses no framework and in one that does. Components that work in both are the reason this technology exists.
Write a custom element <star-rating> in plain JavaScript, no libraries, with Shadow DOM. Attributes: value (0 to max), max (default 5), name. Reflect value as a property. Behavior: click a star to set the value; Left and Right arrow keys change it; Home and End jump to 0 and max. It has role="slider" with aria-valuenow, aria-valuemin and aria-valuemax. Form: make it form-associated with ElementInternals so its value submits under `name`. Styling: colors from CSS custom properties --star-on and --star-off. Do not build: half stars, tooltips. Done when: a plain HTML page with a form shows the right value in FormData after I click the third star, and keyboard use matches the description.
05 A page in two languages, one of them right-to-left
A short site in English and Arabic or Hebrew that flips its layout correctly and formats dates, numbers and plurals for each language.
- Stack
- HTML, CSS logical properties, the Intl API.
- Teaches
- dir and lang attributes, margin-inline and padding-inline, Intl.DateTimeFormat, Intl.NumberFormat, plural rules.
- First version
- One layout, two languages, switched by a link. No left or right in the CSS at all, only start and end.
- Stretch goal
- A language picker that follows the URL (/en/, /ar/), correct hreflang tags, and a plural message such as “1 item” and “3 items” from a message table.
- Time
- 7 to 11 hours.
Replace margin-left with margin-inline-start everywhere and the layout mirrors itself. Icons that show direction, such as arrows, still need flipping by hand. Have a fluent reader review the translated text; machine translation is a draft, not a result.
Where do I find a web project that someone actually wants?
Pair a platform skill with a real problem. The board at Post your build ideas collects app ideas that people will not build themselves. Browse all ideas, or categories like design tools and home and family, and look for one that is mostly a good page: a calculator, a checklist, a printable form. Every idea has a generated build prompt you can paste into Claude Code, Cursor or Lovable, then judge the result against the checks above.
If you have a page idea you will not build, post it. It needs no account.
Frequently asked questions
What web development project should I build first?
Rebuild one real landing page from a screenshot in plain HTML and CSS, at three screen widths. It teaches layout, spacing and semantic structure, needs no tools, and produces something you can show. Do it before you learn a framework.
Do I need JavaScript for web development projects?
Not for many of the best ones. A pricing page, a print invoice and a dark mode need almost none. Learn enough JavaScript for events, fetch and the DOM, and use HTML and CSS for everything they can do natively. Pages built that way tend to be faster and more accessible.
How do I make a web development project stand out?
Add evidence. A performance report with before and after numbers, a note on which accessibility criteria you checked, and a README that explains what you chose not to build all show judgement. Reviewers see many pages that look good and few that explain themselves.
Should I use a framework for these projects?
Not at first. Build several with plain HTML, CSS and JavaScript so you learn what a framework is doing for you. Then rebuild one in React or another framework and compare what became easier and what became heavier.
How do I test a web page for accessibility?
Unplug your mouse and use the page with the Tab key. Check that focus is always visible and the order makes sense. Run a contrast checker and an automated accessibility checker, then read the WCAG 2.2 criteria for anything they cannot judge, such as meaningful link text.
Where can I host a web development project?
Static pages need only a static host, such as GitHub Pages, Netlify, Cloudflare Pages or Vercel. Service workers need HTTPS, which these hosts provide. Put the live link and a screenshot at the top of the project’s README.
Created with AI assistance and edited for this site. Examples are illustrative and do not represent customer research. About the publisher.