Building Contact Forms

Contact forms are essential for websites—they let visitors reach out to you directly. In this tutorial, you’ll learn how to build professional contact forms with various input types, validation, and best practices for user experience!

Why Contact Forms Matter

Contact forms provide a structured way for users to send you messages without exposing your email address to spam bots. They also allow you to collect exactly the information you need in a consistent format.

Benefits of contact forms:

Basic Contact Form Structure

Every contact form needs these essential elements:

Here’s a simple contact form:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact Us</title>
</head>
<body>
<h1>Get in Touch</h1>
<form>
  <label for="name">Name:</label>
  <input type="text" id="name" name="name" required>

  <label for="email">Email:</label>
  <input type="email" id="email" name="email" required>

  <label for="message">Message:</label>
  <textarea id="message" name="message" rows="5" required></textarea>

  <button type="submit">Send Message</button>
</form>
</body>
</html>

Form Attributes Explained

The <form> Tag

<form action="/submit-form" method="post">
<!-- Form fields go here -->
</form>

Best practice: Use method="post" for contact forms to keep data private.

Input Types

Different input types provide different interfaces and validation:

<!-- Text input -->
<input type="text" name="fullname" placeholder="John Doe">

<!-- Email input (validates email format) -->
<input type="email" name="email" placeholder="[email protected]">

<!-- Phone number -->
<input type="tel" name="phone" placeholder="(555) 123-4567">

<!-- Number input -->
<input type="number" name="age" min="1" max="120">

<!-- URL input -->
<input type="url" name="website" placeholder="https://example.com">

<!-- Date picker -->
<input type="date" name="preferred-date">

Building a Complete Contact Form

Let’s build a professional contact form with styling:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact Form</title>
<style>
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    padding: 20px;
  }

  .container {
    max-width: 600px;
    margin: 0 auto;
    background: white;
    padding: 30px;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  }

  h1 {
    margin-bottom: 20px;
    color: #333;
  }

  form {
    display: flex;
    flex-direction: column;
    gap: 15px;
  }

  label {
    font-weight: bold;
    margin-bottom: 5px;
    color: #555;
  }

  input, textarea, select {
    width: 100%;
    padding: 12px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 16px;
    font-family: Arial, sans-serif;
  }

  input:focus, textarea:focus, select:focus {
    outline: none;
    border-color: #4CAF50;
  }

  textarea {
    resize: vertical;
  }

  button {
    background-color: #4CAF50;
    color: white;
    padding: 15px;
    border: none;
    border-radius: 4px;
    font-size: 16px;
    font-weight: bold;
    cursor: pointer;
    transition: background-color 0.3s;
  }

  button:hover {
    background-color: #45a049;
  }

  .required {
    color: red;
  }
</style>
</head>
<body>
<div class="container">
  <h1>Contact Us</h1>
  <form action="/submit-contact" method="post">
    <div>
      <label for="name">Full Name <span class="required">*</span></label>
      <input type="text" id="name" name="name" required>
    </div>

    <div>
      <label for="email">Email Address <span class="required">*</span></label>
      <input type="email" id="email" name="email" required>
    </div>

    <div>
      <label for="phone">Phone Number</label>
      <input type="tel" id="phone" name="phone">
    </div>

    <div>
      <label for="subject">Subject <span class="required">*</span></label>
      <input type="text" id="subject" name="subject" required>
    </div>

    <div>
      <label for="message">Message <span class="required">*</span></label>
      <textarea id="message" name="message" rows="6" required></textarea>
    </div>

    <button type="submit">Send Message</button>
  </form>
</div>
</body>
</html>

Adding a Dropdown Select Menu

Sometimes you want users to choose from predefined options:

<label for="subject-type">Subject Type:</label>
<select id="subject-type" name="subject-type" required>
<option value="">-- Please choose --</option>
<option value="general">General Inquiry</option>
<option value="support">Technical Support</option>
<option value="sales">Sales Question</option>
<option value="feedback">Feedback</option>
</select>

Best practices:

Form Validation

HTML5 provides built-in validation attributes:

<!-- Required field -->
<input type="text" name="name" required>

<!-- Minimum length -->
<input type="text" name="username" minlength="3" required>

<!-- Maximum length -->
<input type="text" name="bio" maxlength="500">

<!-- Pattern (regex) validation -->
<input type="text" name="zip" pattern="[0-9]{5}"
     placeholder="12345" title="5-digit ZIP code">

<!-- Email validation (automatic) -->
<input type="email" name="email" required>

<!-- Number range -->
<input type="number" name="age" min="18" max="100" required>

Checkbox and Radio Buttons

For yes/no questions or multiple choice:

<!-- Checkbox (multiple selections allowed) -->
<fieldset>
<legend>How can we help you?</legend>
<label>
  <input type="checkbox" name="help" value="website">
  Website Development
</label>
<label>
  <input type="checkbox" name="help" value="design">
  Design Services
</label>
<label>
  <input type="checkbox" name="help" value="consulting">
  Consulting
</label>
</fieldset>

<!-- Radio buttons (only one selection) -->
<fieldset>
<legend>Preferred contact method:</legend>
<label>
  <input type="radio" name="contact-method" value="email" checked>
  Email
</label>
<label>
  <input type="radio" name="contact-method" value="phone">
  Phone
</label>
<label>
  <input type="radio" name="contact-method" value="text">
  Text Message
</label>
</fieldset>

Advanced Contact Form with All Features

Here’s a comprehensive contact form with multiple input types:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced Contact Form</title>
<style>
  body {
    font-family: Arial, sans-serif;
    max-width: 700px;
    margin: 40px auto;
    padding: 20px;
    background-color: #f9f9f9;
  }

  form {
    background: white;
    padding: 30px;
    border-radius: 8px;
    box-shadow: 0 2px 5px rgba(0,0,0,0.1);
  }

  .form-group {
    margin-bottom: 20px;
  }

  label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
    color: #333;
  }

  input, textarea, select {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 16px;
  }

  input:focus, textarea:focus, select:focus {
    border-color: #007bff;
    outline: none;
  }

  .checkbox-group, .radio-group {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }

  .checkbox-group label, .radio-group label {
    font-weight: normal;
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .checkbox-group input, .radio-group input {
    width: auto;
  }

  button {
    background-color: #007bff;
    color: white;
    padding: 12px 30px;
    border: none;
    border-radius: 4px;
    font-size: 16px;
    cursor: pointer;
    font-weight: bold;
  }

  button:hover {
    background-color: #0056b3;
  }

  .required {
    color: red;
  }
</style>
</head>
<body>
<form action="/submit" method="post">
  <h1>Contact Us</h1>
  <p>We'd love to hear from you! Fill out the form below.</p>

  <div class="form-group">
    <label for="full-name">Full Name <span class="required">*</span></label>
    <input type="text" id="full-name" name="full-name" required>
  </div>

  <div class="form-group">
    <label for="email">Email Address <span class="required">*</span></label>
    <input type="email" id="email" name="email" required>
  </div>

  <div class="form-group">
    <label for="phone">Phone Number</label>
    <input type="tel" id="phone" name="phone" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
           placeholder="123-456-7890">
  </div>

  <div class="form-group">
    <label for="company">Company Name</label>
    <input type="text" id="company" name="company">
  </div>

  <div class="form-group">
    <label for="inquiry-type">Type of Inquiry <span class="required">*</span></label>
    <select id="inquiry-type" name="inquiry-type" required>
      <option value="">-- Select One --</option>
      <option value="general">General Question</option>
      <option value="support">Technical Support</option>
      <option value="sales">Sales Inquiry</option>
      <option value="partnership">Partnership Opportunity</option>
    </select>
  </div>

  <div class="form-group">
    <label>Services Interested In:</label>
    <div class="checkbox-group">
      <label>
        <input type="checkbox" name="services" value="web-dev">
        Web Development
      </label>
      <label>
        <input type="checkbox" name="services" value="design">
        Design
      </label>
      <label>
        <input type="checkbox" name="services" value="consulting">
        Consulting
      </label>
      <label>
        <input type="checkbox" name="services" value="marketing">
        Marketing
      </label>
    </div>
  </div>

  <div class="form-group">
    <label>Preferred Contact Method:</label>
    <div class="radio-group">
      <label>
        <input type="radio" name="contact-pref" value="email" checked>
        Email
      </label>
      <label>
        <input type="radio" name="contact-pref" value="phone">
        Phone
      </label>
    </div>
  </div>

  <div class="form-group">
    <label for="message">Your Message <span class="required">*</span></label>
    <textarea id="message" name="message" rows="6"
              minlength="10" required></textarea>
  </div>

  <div class="form-group">
    <label>
      <input type="checkbox" name="newsletter" value="yes">
      Subscribe to our newsletter
    </label>
  </div>

  <button type="submit">Send Message</button>
</form>
</body>
</html>

Accessibility Best Practices

Always Use Labels

Labels help screen readers and make the entire area clickable:

Problematic example:

<input type="text" name="name">

Improved example:

<label for="name">Name:</label>
<input type="text" id="name" name="name">

Group related form controls together:

<fieldset>
<legend>Personal Information</legend>
<label for="first-name">First Name:</label>
<input type="text" id="first-name" name="first-name">

<label for="last-name">Last Name:</label>
<input type="text" id="last-name" name="last-name">
</fieldset>

Provide Clear Error Messages

Use the title attribute or custom JavaScript to provide helpful error messages:

<input type="text"
     name="username"
     pattern="[a-zA-Z0-9]{3,15}"
     title="Username must be 3-15 characters, letters and numbers only"
     required>

Common Mistakes to Avoid

Missing Name Attributes

Problematic example:

<input type="text" id="email">

Improved example:

<input type="text" id="email" name="email">

Without name, the data won’t be submitted!

Forgetting Labels

Problematic example:

<input type="text" name="phone" placeholder="Phone Number">

Improved example:

<label for="phone">Phone Number:</label>
<input type="text" id="phone" name="phone" placeholder="555-1234">

Placeholders disappear when typing—always use labels!

Not Using the Right Input Type

Problematic example:

<input type="text" name="email">

Improved example:

<input type="email" name="email">

Using the right type enables proper validation and mobile keyboard!

Form Submission Handling

Note: HTML forms alone can’t send emails. You need either:

  1. Server-side processing (PHP, Node.js, Python, etc.)
  2. Form handling service (Formspree, Netlify Forms, etc.)
  3. JavaScript with API (fetch, axios with backend)

Here’s an example with a form service:

<!-- Using Formspree (example) -->
<form action="https://formspree.io/f/YOUR_FORM_ID" method="POST">
<label for="email">Your Email:</label>
<input type="email" id="email" name="email" required>

<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea>

<button type="submit">Send</button>
</form>

Try It Yourself

Ready to practice? Try these challenges:

Challenge 1: Simple Feedback Form (Basic)

Create a feedback form with:

Challenge 2: Job Application Form (Intermediate)

Build a job application form with:

Challenge 3: Multi-Step Registration (Advanced)

Create a registration form with:

What You Learned

Congratulations! You now know:

Next Steps

Now that you can create contact forms, explore these related tutorials:

Want to experiment with forms? Try our interactive HTML editor!

Back to all tutorials