Select & Textarea
<select> gives users a dropdown of pre-defined options — or a multi-select list. <textarea> gives them a resizable multi-line text area for longer input. And <datalist> adds autocomplete suggestions to any text input. Together, these three elements cover almost every remaining form use case.
The <select> Element
A <select> renders a dropdown menu. It contains <option> children — each with a value (what gets submitted) and display text (what the user sees).
<label for="country">Country</label> <select id="country" name="country" required> <!-- Empty first option acts as a placeholder --> <option value="" disabled selected>Select a country…</option> <option value="gb">United Kingdom</option> <option value="us">United States</option> <option value="ca">Canada</option> </select>
Use <optgroup> to visually group related options under a non-selectable heading:
<select name="course"> <optgroup label="Beginner"> <option value="html-basics">HTML Fundamentals</option> <option value="css-basics">CSS Fundamentals</option> </optgroup> <optgroup label="Advanced"> <option value="js-advanced">Advanced JavaScript</option> <option value="react">React & Next.js</option> </optgroup> </select>
Multi-Select & Size
Add multiple to let users select more than one option (hold Ctrl/Cmd to select multiple). Add size to show N options visible at once without a dropdown.
<label for="skills">Skills (hold Ctrl/Cmd for multiple)</label> <select id="skills" name="skills" multiple size="4"> <option value="html">HTML</option> <option value="css">CSS</option> <option value="js" selected>JavaScript</option> <option value="python">Python</option> </select>
The <textarea> Element
Unlike <input>, <textarea> is a two-tag element that accepts multi-line text. Its initial content goes between the tags (not in a value attribute). Control size with rows and cols, or better — with CSS.
<label for="bio">About You</label> <textarea id="bio" name="bio" rows="5" placeholder="Tell us about yourself…" maxlength="500" required ></textarea> <!-- No content between tags = empty textarea (correct) --> <!-- Any whitespace between tags appears as initial content -->
| Attribute | Effect on textarea |
|---|---|
rows | Initial height in lines of text |
cols | Width in character widths (use CSS instead) |
maxlength | Maximum characters allowed |
minlength | Minimum characters for validation |
placeholder | Hint text shown when empty |
readonly | Cannot be edited; value is still submitted |
resize: none (CSS) | Prevents the user from dragging to resize |
datalist — Autocomplete Suggestions
<datalist> provides a list of suggestions for a text input without restricting the user to those values. Connect a datalist to an input via matching id and list attributes.
<label for="browser">Favourite Browser</label> <input type="text" id="browser" name="browser" list="browsers" placeholder="Type to search…"> <datalist id="browsers"> <option value="Chrome"> <option value="Firefox"> <option value="Safari"> <option value="Edge"> </datalist>
<select> when the user must choose from a fixed list. Use <datalist> when you want to suggest options but also allow free-form input — like a city name search where users might type a city not in the list.The form should include:
- Name (text, required, minlength 2)
- Email (email, required)
- Phone (tel)
- Date of Birth (date, max attribute set to 18 years ago)
- Job Role (select with optgroup: "Engineering" → Frontend / Backend / Full-Stack; "Design" → UX / Graphic)
- Experience Level (radio: Junior / Mid / Senior)
- Tech Stack (multiple select or checkboxes: HTML, CSS, JS, Python, etc.)
- Cover Letter (textarea, minlength 100, maxlength 2000, rows=8)
- CV Upload (file, accept=".pdf,.doc,.docx")
- Terms agreement (checkbox, required)
Use fieldsets to group related sections. Apply :valid/:invalid CSS styling. All inputs must have proper label associations.
Show hints
- For "18 years ago" max date: use JS
let d = new Date(); d.setFullYear(d.getFullYear()-18); input.max = d.toISOString().split('T')[0] - Multiple select: submitted as repeated key=value pairs — your server must handle arrays
- File uploads require
enctype="multipart/form-data"on the form - A required checkbox is only valid when checked — add
requiredto the checkbox input