Formclick

How to Create an HTML Contact Form

Build a contact form that looks professional, blocks spam and delivers every message to your inbox — with plain HTML and CSS, no server required.

FFormclick Team4 min read
Close-up of a hand holding a smartphone displaying email app against a green background.
Photo by Solen Feyissa on Pexels
On this page
  1. What a good contact form needs
  2. The HTML
  3. The CSS
  4. Connecting it to your inbox
  5. Showing a success message
  6. Optional extras
  7. Common contact form mistakes
  8. Next steps

A contact form is often the first form anyone adds to a website — and also the one most often done badly. Messages go missing, spam floods in, or the form only works if you set up a mail server.

This guide builds a contact form that does the job properly: clear fields, sensible validation, spam protection, and reliable delivery to your inbox. It works on any website, including static hosts like GitHub Pages and Netlify.

What a good contact form needs

  • Only essential fields. Name, email and message. Every extra field lowers the number of people who finish.
  • A valid reply address. Use type="email" so you can actually write back.
  • Spam protection that doesn't punish real people.
  • Clear feedback after sending, so people know it worked.
  • Reliable delivery — the message must reach you.

The HTML

<form class="contact" action="https://api.formclick.io/submit" method="POST">
  <!-- Your Formclick access key -->
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY">
  <input type="hidden" name="subject" value="New contact form message">
  <input type="hidden" name="from_name" value="Website Contact Form">

  <!-- Honeypot spam trap -->
  <input type="checkbox" name="botcheck" class="hp" tabindex="-1" autocomplete="off">

  <h2>Get in touch</h2>
  <p>We usually reply within one business day.</p>

  <div class="row">
    <div class="field">
      <label for="name">Name</label>
      <input id="name" name="name" type="text" autocomplete="name" required>
    </div>
    <div class="field">
      <label for="email">Email</label>
      <input id="email" name="email" type="email" autocomplete="email" required>
    </div>
  </div>

  <div class="field">
    <label for="message">How can we help?</label>
    <textarea id="message" name="message" rows="6" required minlength="10"></textarea>
  </div>

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

<script src="https://cdn.formclick.io/formclick.min.js"></script>

What each hidden field does:

  • access_key tells Formclick which form (and inbox) the message belongs to.
  • subject becomes the subject line of your notification email.
  • from_name is the sender name you'll see in your inbox.
  • botcheck is a hidden honeypot. People never see or tick it; simple bots fill in every field, so submissions with it ticked are discarded.

Because the visitor's email is in a field named email, you can reply to the notification directly.

The CSS

.contact {
  max-width: 560px;
  margin: 40px auto;
  padding: 32px;
  background: #fff;
  border: 1px solid #e6e6f0;
  border-radius: 18px;
  font-family: system-ui, sans-serif;
}
.contact h2 { margin: 0 0 4px; }
.contact p  { margin: 0 0 24px; color: #64748b; }

.row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.field { margin-bottom: 16px; }
.field label {
  display: block;
  margin-bottom: 6px;
  font-weight: 600;
  font-size: 14px;
}
.field input,
.field textarea {
  width: 100%;
  padding: 12px 14px;
  font: inherit;
  border: 1px solid #d4d4e0;
  border-radius: 10px;
  transition: border-color .15s, box-shadow .15s;
}
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: #645cec;
  box-shadow: 0 0 0 3px rgba(100, 92, 236, .2);
}
.contact button {
  width: 100%;
  padding: 14px;
  font: inherit;
  font-weight: 700;
  color: #fff;
  background: #645cec;
  border: 0;
  border-radius: 10px;
  cursor: pointer;
}
.contact button:hover { background: #4f46e5; }

.hp { display: none; }

@media (max-width: 560px) {
  .row { grid-template-columns: 1fr; gap: 0; }
}

The two-column row collapses to a single column on small screens, so the form stays comfortable on phones.

Connecting it to your inbox

  1. Sign up for Formclick (the free plan includes 250 submissions a month).
  2. Create a form and copy its access key.
  3. Replace YOUR_ACCESS_KEY in the HTML.
  4. Publish the page and send a test message.

Every message is emailed to you and saved in your dashboard, so nothing is lost if an email lands in spam.

Showing a success message

The formclick.min.js script at the bottom submits the form in the background, shows a loading state on the button and displays a success or error message in place. If you would rather not use JavaScript, delete the script and add a redirect instead:

<input type="hidden" name="redirect" value="https://yourwebsite.com/thanks.html">

On the Free plan the thank-you page needs to be on the same website as the form; paid plans can redirect anywhere.

Optional extras

A topic dropdown

Useful if messages go to different people:

<div class="field">
  <label for="topic">Topic</label>
  <select id="topic" name="topic" required>
    <option value="">Choose a topic…</option>
    <option>Sales</option>
    <option>Support</option>
    <option>Partnerships</option>
  </select>
</div>

A phone number

Make it optional — and use type="tel" so phones show a number pad:

<input id="phone" name="phone" type="tel" autocomplete="tel">

Consent checkbox

If you'll add people to a mailing list, ask clearly and separately:

<label>
  <input type="checkbox" name="marketing_opt_in" value="yes">
  Send me occasional product updates
</label>

Common contact form mistakes

  • Using mailto: as the action. It opens the visitor's email app (if they have one) instead of sending anything. Most people give up.
  • Missing name attributes. Fields without a name are silently dropped.
  • Placeholder-only labels. The hint disappears as soon as someone types.
  • CAPTCHAs on every form. Start with a honeypot; add reCAPTCHA or Turnstile only if spam gets through.
  • No confirmation. People resubmit when they aren't sure it worked.

Next steps

Prefer a finished design? Our contact form template is ready to copy, and there are variations for business inquiries and callback requests. To make sure it looks great on every screen, read How to Create a Responsive HTML Form.

Found this useful? Share it.

All articles