HTML Forms: Inputs, Labels, and GET vs POST
A form gathers input from a visitor and sends it somewhere to be processed: a contact message, a login, a checkout, a registration. HTML builds the form itself; a server-side language like PHP, Node, or Python does something with the data once it arrives.
This is the written version of my HTML forms video, part of my HTML beginners course. It's embedded near the top.
Key Takeaways
<form>wraps every input you want submitted together. Anything outside the tag doesn't get included.method="get"puts data in the URL, visible and cached;method="post"puts it in the request body, invisible and uncached. Usepostfor anything sensitive or write-oriented.- Pair a
<label>with its<input>usingforandid, so clicking the label activates the field. text,email, andpasswordare input types;emailgets free browser-level validation.- Radio buttons let you pick one option per group; checkboxes let you pick several, and a checkbox group needs
name="field[]"to send more than one value.
The form tag
<form> needs to wrap everything you want submitted together:
<form name="registration" action="/register.php" method="post">
<!-- inputs go here -->
</form>nameidentifies the form, mostly useful in JavaScript or when a page has more than one form.actionis where the data goes when the form submits.methodis how it gets sent:getorpost.
GET vs POST
Both methods send data from the browser to the server, but differently. GET appends data to the URL as visible name/value pairs (?name=Scott&email=...), which the browser caches. Reserve it for reads that don't involve sensitive data. POST sends data in the request body instead, invisible to the URL bar and never cached, which makes it the right choice for anything sensitive, anything that writes data, or anything larger than a short read. In practice, most forms you build should use post.
Labels and inputs
Every input should have a matching <label>, connected by for and id:
<label for="first-name">First Name</label>
<input type="text" id="first-name" name="first-name">Without that connection, clicking the label text does nothing. With it, clicking "First Name" focuses the input directly, which matters for usability and is required for many assistive technologies to announce the field correctly. id values need to be unique on the page; reuse one and both the browser and your visitor get confused about which field a label belongs to.
Text-based inputs
text, email, and password all render as a single-line field, but the type changes real behavior:
<label for="email">Email</label>
<input type="email" id="email" name="email">
<label for="password">Password</label>
<input type="password" id="password" name="password">type="email" gets you free validation: browsers refuse to submit an obviously malformed address and can offer to autofill a saved one. type="password" masks what's typed. Plain type="text" does neither; use it for anything that isn't a recognized specific type.
Dropdowns
A dropdown uses <select> with <option> elements inside it, not an <input>:
<label for="favorite-fruit">Favorite Fruit</label>
<select id="favorite-fruit" name="favorite-fruit">
<option value=""></option>
<option value="apple">Apple</option>
<option value="banana">Banana</option>
</select>The value on each <option> is what actually gets sent; the text between the tags is only what the visitor sees. They're often the same, but don't have to be, useful when the display label is more descriptive than the value your database expects.
Radio buttons and checkboxes
Radio buttons let a visitor pick exactly one option from a group; checkboxes let them pick any number. Group radio buttons by giving them the same name:
<label><input type="radio" name="favorite-color" value="red"> Red</label>
<label><input type="radio" name="favorite-color" value="blue"> Blue</label>Checkboxes work the same way for grouping, but since more than one can be checked, the field name needs [] so the server receives every checked value instead of just the last one:
<label><input type="checkbox" name="favorite-pets[]" value="dog"> Dog</label>
<label><input type="checkbox" name="favorite-pets[]" value="cat"> Cat</label>Without the [], most backend languages only see whichever checkbox happened to submit last, silently dropping the rest.
Text areas
For freeform, multi-line input, use <textarea> instead of <input>:
<label for="comments">Comments</label>
<textarea id="comments" name="comments" rows="4" cols="50"></textarea>rows and cols set a starting size; CSS width and height give you more precise control if you need it.
What happens after submit
Once a form submits, a server-side script (PHP, Node, Python, whatever the backend runs) validates the data. If something's wrong, invalid input, a missing required field, the response typically sends the visitor back to the form with an error message and the bad field highlighted, while preserving whatever they'd already entered correctly. If everything checks out, the server does whatever the form exists to do: save a record, send an email, add an address to a list, and usually redirects to a success message afterward. None of that logic lives in the HTML; the form only defines what gets collected and where it goes.
See MDN's guide to forms for the full set of input types and validation attributes beyond what's covered here.
A note on layout
Older form tutorials, including earlier versions of this one, often used an HTML <table> purely to line up labels and inputs. Tables should hold tabular data, not handle visual layout; use CSS (Flexbox or Grid, or even just display: block labels stacked above their inputs) to arrange a form instead.
Where to go next
HTML Tables, HTML Iframes, and HTML Links and Anchor Tags round out the remaining structural elements in this course.
FAQ
What's the difference between GET and POST?
GET sends data as visible URL parameters and gets cached by the browser; use it only for non-sensitive reads. POST sends data in the request body, invisible and uncached; use it for anything sensitive, anything that writes data, or larger submissions.
Why doesn't clicking my label focus the input?
The label needs a for attribute matching the input's id. Without that connection, the browser has no way to know which input the label belongs to.
Why does my checkbox only send one value when several are checked?
The field name needs [], like name="options[]", so the server treats it as an array and receives every checked value instead of overwriting itself with just the last one.
What does type="email" actually do?
It tells the browser to validate that the entered text looks like a valid email address before allowing submission, and it can trigger email-specific autofill and mobile keyboard layouts. Plain type="text" does none of that.
Should I use a table to lay out my form?
No. Tables are for tabular data. Use CSS, Flexbox or Grid for more complex layouts, or simple block-level stacking for a straightforward form, to arrange labels and inputs.


