Course outline
Full-Stack course / Tools and the web

A contact form everyone can use

Project

How to fetch and submit this exercise

Once: install the tool and connect your account.

curl -fsSL https://gonomicon.com/install.sh | sh
gonomicon login

Each exercise: download it, edit the file named in the instructions, then submit.

gonomicon fetch fs-week-1/07-03-accessible-contact-form
cd 07-03-accessible-contact-form
gonomicon submit

The runner depends on the exercise: JavaScript/TypeScript/React labs run with Vitest, Python labs with pytest, and config-file labs (Docker, CI, Terraform, Nginx) are checked by parsing your file. gonomicon test runs the visible checks on your computer first; submitting also runs the hidden checks on our server.

Add a contact form to your personal site that works just as well with a keyboard and a screen reader as it does with a mouse.

Worked example. The lesson's bakery signup form showed the shape: a <label for="bakery-email"> wired to <input id="bakery-email"> by a matching id, type="email" with required on the email field, and a :focus-visible rule giving every field a visible outline when reached by Tab. Your contact form reuses that same shape with different fields.

Your task. index.html already has a personal site with <header>, <nav>, and <main> holding an about and a projects section. Inside <main>, build the contact section's form with:

  • a text <input> for the visitor's name, with a real <label> pointing at it
  • an <input type="email" required> for their email, with a real <label> pointing at it
  • a <textarea> for their message, with a real <label> pointing at it
  • a <button type="submit"> with real button text (not empty)

Then, in styles.css, add a :focus-visible rule covering all four controls that gives each one a visible outline (or other clearly visible change) when it has keyboard focus.

Rules.

  • The form must sit inside its own <section> (reuse the existing contact section, don't add a stray <div> around it instead).
  • Every field's label must be a real <label for="..."> matching that field's id — a placeholder can still be there as a hint, but it can never be the only thing identifying the field.
  • Don't hide the default focus outline (outline: none) on these controls without replacing it with your own visible :focus-visible style.

What you'll practice: wiring labels to fields correctly, choosing the right input type and required attribute, and giving keyboard users a focus style that never disappears.

Run it

gonomicon fetch fs-week-1/07-03-accessible-contact-form
cd 07-03-accessible-contact-form
gonomicon test
gonomicon submit

Hints

  1. Every field needs its own <label for="..."> pointing at that field's id — a placeholder is not a substitute, since it disappears once you start typing and isn't reliably announced by a screen reader.
  2. The email field needs both type="email" and the required attribute. The name and message fields don't need to be required — only follow the lesson's own form shape for which field is required.
  3. Add one CSS rule using :focus-visible that covers the name input, the email input, the textarea, and the submit button — either one shared selector list (input:focus-visible, textarea:focus-visible, button:focus-visible) or a wildcard like *:focus-visible — and give it a real outline (not outline: none) so keyboard users can always see where focus is.