Theory

Responsiveness and forms

Two topics close out the track: making the whole page fit a phone, and giving a visitor a way to type something back. Both come with an honest limit you should understand before you build.

Responsive design and media queries

You already have one piece of responsiveness — the gallery's auto-fill grid reflows on its own, no rules attached to any width. But the rest of the page doesn't: on a phone the nav still wears its desktop spacing. For per-width adjustments you use a media query — a block of CSS that applies only when a condition about the screen is true:

@media (max-width: 640px) {
  .navbar { flex-wrap: wrap; }
  .grid { grid-template-columns: 1fr; }
}

Everything inside applies only at 640px wide and below. That max-width is the key to which way the CSS is built:

  • Desktop-first — the base rules describe the wide layout, and max-width queries trim it down for smaller screens. This stylesheet is written this way.
  • Mobile-first — the base rules describe the phone layout, and min-width queries add to it as the screen grows. Many teams prefer this: the base stays lean for the least-powerful devices, and each larger screen only ever adds. It's worth knowing as the other approach — but here you follow the stylesheet you have, which is desktop-first.

The media query isn't doing the heavy lifting for the gallery — auto-fill already did that. It's fine-tuning the edges: forcing a clean single column on a phone (rather than a cramped two), letting the nav wrap, tightening the page padding. That's the healthy division — responsive by default where you can, media queries for the specific spots that need a nudge.

Forms: labels first

A form field without a label is a guess. Every input gets a <label>, tied to it by matching for and id:

<label for="contact-email">Email</label>
<input type="email" id="contact-email" name="email">

That link does two real jobs: clicking the label focuses the field (a bigger target, easier on touch), and a screen reader announces the field by its label instead of "edit text, blank." A placeholder is not a label — it vanishes the moment you type, and grey placeholder text usually fails contrast. Use both: a label that stays, a placeholder that hints.

Input types earn their keep

type is not decoration. type="email" gives a phone the @-key keyboard and lets the browser check the value looks like an email. A <select> is the right control for one-of-a-fixed-set. A <textarea> is for long text. Choosing the right element means the browser does work you'd otherwise write by hand.

Native validation — the part that fully works

Add required to a field and the browser will not submit an empty one — it stops, focuses the field, and shows its own message, in the user's own language, with no code from you:

<input type="email" id="contact-email" name="email" required>
<textarea id="contact-message" minlength="20" required></textarea>

required, type="email", minlength="20" — the browser enforces all three before anything is sent. This is the whole point of the beat: a large slice of form validation is built into HTML, and reaching for JavaScript before you've used it is wasted effort.

The honest limit: what happens after Send

Here's the part a static page can't do, and you should meet it head-on rather than be surprised by it. Native validation runs before submit. What happens after — actually doing something with the message — needs somewhere to send it, and that means a server or JavaScript. A static page has neither.

So when you fill the form correctly and press Send message, the browser does its plain default: it reloads the page with your fields tacked onto the URL as a query string (?name=…&email=…) and shows no confirmation. That is expected, not a bug you introduced — the form validated, then had nowhere to deliver to. Sending it for real is exactly what the two later tracks add: the server-side track receives and stores it on a backend; the client-side track intercepts the submit in JavaScript and calls an API. Here, you build the form and its validation correctly, and stop at the honest edge of what HTML and CSS alone can do.