Interactive HTML Forms Tutorial

Build a CSS Property Fandom Survey

0% Complete

What You'll Build

Goal: Build a playful survey form about favorite CSS properties while learning form structure, input types, and validation. We know you have opinions about CSS properties. This is a safe space to share them.

What you'll learn:

  • Creating forms with proper label/input relationships
  • Using radio buttons for single selection
  • Using checkboxes for multiple selections
  • Adding dropdowns and textareas
  • Implementing native HTML validation

Part A β€” Text Inputs and Labels

A1) Understanding Labels and Inputs

Goal: Create your first form with properly associated labels and inputs.

Forms collect user input. Every input needs a labelβ€”not just for sighted users, but for screen readers and form autofill. Let's start with the basics.

πŸ“š Research checkpoint: Read MDN: Your first form.

Key concepts to understand:

  • <form> β€” Container for all form elements
  • <label> β€” Descriptive text for an input
  • <input> β€” Field where users enter data
  • for attribute β€” Connects label to input via id
πŸ’‘ The magic of for/id connection: When a label's for attribute matches an input's id, clicking the label focuses the input. This is crucial for accessibility and makes forms easier to use on mobile!

A2) Build Your First Inputs

Your task: In the CodePen workspace, add two form fields inside the <form id="property-survey">.

  1. Add a text input for name with id="name"
  2. Add a label with for="name" that says "Your name (or alias)"
  3. Add an email input with id="email" and type="email"
  4. Add a label with for="email" that says "Email (for CSS newsletter)"

Structure each label/input pair in a container:

<div class="form-group">
  <label for="name">Your name (or alias)</label>
  <input type="text" id="name" name="name">
</div>

<div class="form-group">
  <label for="email">Email (for CSS newsletter)</label>
  <input type="email" id="email" name="email">
</div>
πŸ“ Note about name attribute: The name attribute is what gets sent to the server when the form submits. It's different from id (which is for label association). You often make them the same for simplicity.

βœ… Checkpoint A

  • Form has <form> wrapper with id="property-survey"
  • Name input has matching label with for="name"
  • Email input has type="email" and matching label
  • Clicking labels focuses inputs

πŸ€” Reflect (2–3 sentences):

Click on a label. What happens? Why does this matter for accessibility and mobile users?

Part B β€” Radio Buttons and Fieldsets

B1) Understanding Radio Buttons

Goal: Create a radio button group with proper semantic structure.

Radio buttons let users pick one option from a set. They need special structure: a <fieldset> to group them, a <legend> to describe the group, and matching name attributes.

πŸ“š Research checkpoint: Read MDN: Radio buttons.

Key concepts:

  • <fieldset> β€” Groups related form controls together
  • <legend> β€” Provides a caption for the fieldset
  • Same name: All radios in a group must have the same name attribute
  • Unique id: Each radio needs a unique id for its label
πŸ’‘ Why same name matters: When multiple radios share the same name, the browser knows they're mutually exclusiveβ€”selecting one automatically deselects the others.

B2) Build Your Radio Group

Your task: Add a radio button group to your form.

  1. Add a <fieldset> after your email input
  2. Add a <legend> that says "How did you discover your favorite CSS property?"
  3. Add 3-4 radio buttons, each with:
    • Same name="discovery"
    • Unique id and value
    • A label with matching for attribute
  4. Set checked on one radio by default

Radio button options (pick 3-4):

  • "A tutorial showed me the way"
  • "Stack Overflow called to me"
  • "I discovered it by accident (the best way)"
  • "A senior dev whispered its name"

Example structure:

<fieldset>
  <legend>How did you discover your favorite CSS property?</legend>
  <div class="form-group">
    <input type="radio" id="tutorial" name="discovery" value="tutorial" checked>
    <label for="tutorial">A tutorial showed me the way</label>
  </div>
  <div class="form-group">
    <input type="radio" id="stackoverflow" name="discovery" value="stackoverflow">
    <label for="stackoverflow">Stack Overflow called to me</label>
  </div>
  <!-- more radios -->
</fieldset>

βœ… Checkpoint B

  • Fieldset wraps radio group
  • Legend describes the group
  • All radios share same name="discovery"
  • Each radio has unique id, value, and label
  • One radio is checked by default
  • Only one radio can be selected at a time

πŸ€” Reflect (2–3 sentences):

Try selecting different radios. What happens to the previously selected one? Why do radios need matching name attributes?

Part C β€” Checkboxes for Multiple Selection

C1) Understanding Checkboxes

Goal: Add checkboxes to let users select multiple favorite properties.

Unlike radios, checkboxes allow multiple selections. Each checkbox needs its own unique name and value.

πŸ“š Research checkpoint: Read MDN: Checkboxes.

Key difference from radios:

  • Radios: Same name, pick one
  • Checkboxes: Different name, pick many
πŸ’‘ When to use which: Use radios for "pick one" (e.g., shirt size: S, M, L). Use checkboxes for "select all that apply" (e.g., interests: sports, music, art).

C2) Build Your Checkbox Group

Your task: Add a checkbox group to your form.

  1. Add a new <fieldset> after your radio group
  2. Add a <legend>: "Which properties spark joy? (select all that apply)"
  3. Add 5-6 checkboxes, each with:
    • Type checkbox
    • Unique name (e.g., name="flexbox", name="grid")
    • Unique id and meaningful value
    • A label with matching for

CSS property options (use all 6):

  • flexbox β€” "flexbox β€” The Container Whisperer"
  • grid β€” "grid β€” The Layout Legend"
  • border-radius β€” "border-radius β€” The Corner Softener"
  • box-shadow β€” "box-shadow β€” The Depth Maker"
  • hover β€” ":hover β€” The Interaction Enchanter"
  • transition β€” "transition β€” The Smooth Operator"

Example structure:

<fieldset>
  <legend>Which properties spark joy? (select all that apply)</legend>
  <div class="form-group">
    <input type="checkbox" id="flexbox" name="flexbox" value="flexbox">
    <label for="flexbox">flexbox β€” The Container Whisperer</label>
  </div>
  <div class="form-group">
    <input type="checkbox" id="grid" name="grid" value="grid">
    <label for="grid">grid β€” The Layout Legend</label>
  </div>
  <!-- more checkboxes -->
</fieldset>

βœ… Checkpoint C

  • Fieldset wraps checkbox group
  • Legend describes the group
  • Each checkbox has unique name and id
  • Each checkbox has a value attribute
  • Multiple checkboxes can be selected simultaneously

πŸ€” Reflect (2–3 sentences):

When would you use radio buttons vs checkboxes? Give a real example for each.

Part D β€” Dropdown and Textarea

D1) Understanding Select and Textarea

Goal: Add a dropdown menu (select) and a multi-line text area.

Sometimes you have too many options for radio buttons, or you need longer text input.

πŸ“š Research checkpoints:

When to use each:

  • Select/dropdown: Many options, save space (e.g., country picker, 50 states)
  • Radio buttons: Few options (2-5), need visibility (e.g., shirt size)
  • Textarea: Multi-line text (e.g., comments, descriptions)
  • Input: Single-line text (e.g., name, email)

D2) Add a Dropdown Menu

Your task: Add a <select> dropdown after your checkbox group.

  1. Add a label: "Your desert island CSS property?"
  2. Add a <select> with id="favorite" and name="favorite"
  3. Include a default "Select one..." option with value=""
  4. Add 6 <option> elements (use the same properties from your checkboxes)

Example:

<div class="form-group">
  <label for="favorite">Your desert island CSS property?</label>
  <select id="favorite" name="favorite">
    <option value="">Select one...</option>
    <option value="flexbox">flexbox</option>
    <option value="grid">grid</option>
    <option value="border-radius">border-radius</option>
    <option value="box-shadow">box-shadow</option>
    <option value="hover">:hover</option>
    <option value="transition">transition</option>
  </select>
</div>
πŸ“ Default option with empty value: The first option with value="" acts as a placeholder. We'll use this later for validation!

D3) Add a Textarea

Your task: Add a <textarea> for longer text input.

  1. Add a label: "Write a 3-sentence love letter to your favorite CSS property"
  2. Add a <textarea> with:
    • id="love-letter" and name="love-letter"
    • rows="5" to set the height
    • A placeholder with hint text

Example:

<div class="form-group">
  <label for="love-letter">Write a 3-sentence love letter to your favorite CSS property</label>
  <textarea
    id="love-letter"
    name="love-letter"
    rows="5"
    placeholder="Why does it spark joy? What did it unlock for you?"></textarea>
</div>
πŸ’‘ Textarea vs Input: Textareas automatically wrap text and support multiple lines. They're perfect for comments, descriptions, or any content longer than a sentence.

βœ… Checkpoint D

  • Select has label with matching for/id
  • Select has default option with value=""
  • Select has 6+ options with values
  • Textarea has label with matching for/id
  • Textarea has rows attribute
  • Textarea has placeholder text

πŸ€” Reflect (2–3 sentences):

Why use a textarea instead of a regular text input? What's gained by having multiple lines?

Part E β€” Stretch Goals: Validation and Submit

E1) Add HTML Validation

Goal: Add native HTML validation and a submit button.

HTML has built-in validationβ€”no JavaScript required. Let's use it!

πŸ“š Research checkpoint: Read MDN: Client-side form validation.

Your task:

  1. Add required to your name and email inputs
  2. Verify your email input has type="email" (enables email validation)
  3. Add required to your dropdown (the empty first option allows validation)
  4. Add a submit button: <button type="submit">Submit Your Survey</button>
  5. Test: Try submitting without filling required fields or with an invalid email

Example:

<div class="form-group">
  <label for="name">Your name (or alias)</label>
  <input type="text" id="name" name="name" required>
</div>

<div class="form-group">
  <label for="email">Email (for CSS newsletter)</label>
  <input type="email" id="email" name="email" required>
</div>

<!-- At the end of your form -->
<button type="submit">Submit Your Survey</button>
πŸ’‘ What type="email" gives you: Automatic validation of email format (must contain @), proper mobile keyboard with @ key, and browser-provided error messages!

E2) Optional Polish

Take your form to the next level with these enhancements:

  • Add minlength="50" to your textarea to require thoughtful responses
  • Add maxlength="300" to prevent novels
  • Add pattern attribute for custom validation (e.g., must start with capital letter)
  • Style focus states with :focus or :focus-visible in CSS
  • Style invalid inputs with :invalid pseudo-class

Bonus CSS to try:

input:focus,
select:focus,
textarea:focus {
  outline: 2px solid #3b82f6;
  outline-offset: 2px;
}

input:invalid {
  border-color: #ef4444;
}

input:valid {
  border-color: #10b981;
}

E3) Continue Exploring

More ideas to try in your CodePen:

  • Add a number input: "Rate your CSS confidence 1-10" with min="1" and max="10"
  • Add a range slider: <input type="range">
  • Add a date picker: <input type="date">
  • Add a color picker: <input type="color"> for "Pick your favorite CSS color"
  • Experiment with disabled and readonly attributes
πŸ’‘ Modern HTML has so many input types! text, email, password, number, tel, url, search, date, time, color, range, file... and each one gives you different validation and mobile keyboards!

πŸ€” Final Reflection (2–3 sentences):

Why rely on native HTML validation instead of JavaScript? What are the trade-offs?

Part F β€” Save Your Reflections

F1) Copy reflections to your CodePen

Save your reflections directly in your CodePen HTML so they're preserved with your work.

πŸ“‹ Steps:

  1. Click the "Copy All Reflections" button below
  2. Go to your CodePen HTML editor
  3. Scroll to the very bottom of your HTML (after the closing </form> tag)
  4. Paste your reflections
  5. Your reflections are now saved as an HTML comment in your code!
πŸ’‘ Why save reflections in HTML? By pasting them as an HTML comment at the bottom of your code, they're permanently saved with your project. When you submit your CodePen link, your instructor can view both your code and reflections in one place.

πŸ“€ Submission

What to submit to Canvas

  1. Your CodePen link β€” Make sure your pen is saved and public
  2. That's it! Your reflections are already in your HTML at the bottom
⚠️ Before submitting:
  • Verify your CodePen is saved (not showing "unsaved changes")
  • Test that your CodePen link opens correctly in a new browser tab
  • Test form validation by trying to submit with empty required fields
  • Confirm your reflections are pasted at the bottom of your HTML

Final Checklist

  • Form has name and email inputs with proper labels
  • Radio button group with fieldset and legend
  • Checkbox group for multiple selections
  • Dropdown select with default option
  • Textarea for longer text input
  • Required fields have validation
  • Form has a submit button
  • All reflections are saved in your HTML

Grading Rubric (10 pts)

  • 2 pts β€” Label/input relationships (proper for/id matching, clicking labels works)
  • 2 pts β€” Radio buttons (fieldset, legend, same name, unique ids)
  • 2 pts β€” Checkboxes (fieldset, legend, unique names)
  • 2 pts β€” Select and textarea (proper structure, labels, placeholder)
  • 1 pt β€” Validation (required attributes, submit button, working validation)
  • 1 pt β€” Reflection quality (clear, specific, shows understanding)
πŸŽ‰ Congrats! You've built a complete form with proper semantics, accessibility, and validation. This is a judgment-free zone. Except for float. We judge float.

Your Workspace

Code along as you follow the tutorial β†’