Simple Contact Form in HTML - Copy, Paste, Done

Last updated: March 2026

You don't need a backend, a framework, or any programming knowledge. Here's a simple contact form for your website that you can add in under two minutes. Pure HTML, no dependencies.

The complete form (copy and paste this)

<form action="https://app.formwit.com/api/s/YOUR_FORM_ID" method="POST">
  <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" required></textarea>

  <!-- Spam protection (hidden from users) -->
  <input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off" />

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

That's the entire form. Copy it into your HTML file and follow the three steps below to make it live.

How to make it work (3 steps)

  1. Create a free account - sign up at FormWit (no credit card required).
  2. Create a form - click "Create Form" in your dashboard and copy the endpoint URL.
  3. Replace YOUR_FORM_ID - swap it with the ID from your endpoint URL.

That's it. Every submission goes straight to your email and your FormWit dashboard.

Add basic styling

The form above works but looks like unstyled HTML from 1998. Here's a minimal CSS block that makes it presentable:

form {
  max-width: 480px;
  margin: 0 auto;
  font-family: system-ui, -apple-system, sans-serif;
}

label {
  display: block;
  margin-bottom: 4px;
  font-weight: 600;
  font-size: 14px;
}

input, textarea {
  width: 100%;
  padding: 10px 12px;
  margin-bottom: 16px;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  font-size: 16px;
  font-family: inherit;
  box-sizing: border-box;
}

input:focus, textarea:focus {
  outline: none;
  border-color: #4f46e5;
  box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}

textarea {
  min-height: 120px;
  resize: vertical;
}

button {
  background: #4f46e5;
  color: white;
  padding: 12px 24px;
  border: none;
  border-radius: 6px;
  font-size: 16px;
  cursor: pointer;
}

button:hover {
  background: #4338ca;
}

The key things this CSS handles: box-sizing: border-box prevents inputs from overflowing their container. font-family: inherit on inputs stops browsers from defaulting to monospace. The focus styles give users a visual indicator of which field they're editing. font-size: 16px on inputs prevents iOS Safari from zooming into the form when a user taps a field (anything smaller than 16px triggers the zoom).

Accessibility basics

A simple contact form should be usable by everyone, including people navigating with keyboards and screen readers. The form above already includes the most important accessibility features. Here's why each matters:

Labels linked to inputs

Every <label> in the form uses a for attribute that matches the id of its input:

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

Screen readers announce "Name" when a user tabs to the input. Without the for attribute, screen readers announce "edit text" with no context. Clicking the label text also focuses the associated input, which gives mouse users a larger click target.

Required field indicators

The required attribute does double duty: it triggers browser-native validation (preventing submission until the field is filled) and tells screen readers the field is mandatory. You can also add a visual indicator:

<label for="name">Name <span aria-hidden="true">*</span></label>
<input type="text" id="name" name="name" required aria-required="true" />

The aria-hidden="true" on the asterisk prevents screen readers from announcing "star". The aria-required="true" attribute is redundant when required is present, but some older screen readers handle it more reliably.

Error messages

For a simple form, browser-native validation handles errors automatically. If you want custom error messages, connect them to the input with aria-describedby:

<label for="email">Email</label>
<input type="email" id="email" name="email" required
  aria-describedby="email-error" />
<p id="email-error" class="error" hidden>
  Please enter a valid email address.
</p>

Show the error element with JavaScript when validation fails. The aria-describedby link ensures screen readers announce the error text when the input is focused.

Tab order

As long as your form fields appear in logical order in the HTML source, keyboard navigation works correctly. Don't use tabindex values greater than 0. The honeypot field uses tabindex="-1" to remove it from the tab order entirely, so keyboard users skip over it.

Progressive enhancement tips

The form works without any JavaScript. It submits via a standard HTTP POST and the server handles the redirect. You can layer on JavaScript for a better experience without breaking the baseline:

Inline success message

Replace the default form behavior with a fetch call and show a success message in place of the form:

const form = document.querySelector('form');
const wrapper = form.parentElement;

form.addEventListener('submit', async (e) => {
  e.preventDefault();

  const res = await fetch(form.action, {
    method: 'POST',
    body: new FormData(form),
  });

  if (res.ok) {
    wrapper.innerHTML = '<p>Thanks for your message. We will be in touch.</p>';
  } else {
    const btn = form.querySelector('button');
    btn.textContent = 'Something went wrong. Try again?';
  }
});

If JavaScript fails to load or the user has it disabled, the form still works. It falls back to the standard POST-and-redirect flow. That's progressive enhancement: the base experience works for everyone, and JavaScript users get a nicer version.

Disable the submit button during submission

Prevent double-clicks by disabling the button while the request is in flight:

form.addEventListener('submit', async (e) => {
  e.preventDefault();
  const btn = form.querySelector('button');
  btn.disabled = true;
  btn.textContent = 'Sending...';

  try {
    const res = await fetch(form.action, {
      method: 'POST',
      body: new FormData(form),
    });

    if (res.ok) {
      form.reset();
      btn.textContent = 'Sent!';
    } else {
      btn.textContent = 'Error. Try again?';
      btn.disabled = false;
    }
  } catch {
    btn.textContent = 'Error. Try again?';
    btn.disabled = false;
  }
});

Want a custom thank-you page?

By default, FormWit shows a confirmation page after submission. To redirect users to your own page, add this hidden field inside the form:

<input type="hidden" name="redirect_to" value="https://yoursite.com/thank-you" />

Summary

A simple contact form in HTML doesn't need a backend or any dependencies. An HTML snippet and a form endpoint are all you need. The same approach works on portfolios, landing pages, small business sites, and static site generators. The form is accessible out of the box if you use proper labels and required attributes. Layer on JavaScript for inline success messages and disable-on-submit behavior, but keep the no-JS fallback working.

For more advanced options, see the HTML contact form guide. Browse ready-made styled templates, or read the form to email guide for email-specific setup.

Create your free FormWit account and have a working contact form in under two minutes.

If simplicity is your top priority, see how FormWit compares to FormSubmit or browse all form backend alternatives.

Related guides: HTML contact form · Form to email · Free contact form options · Embed a contact form · Spam protection · Form templates

Frequently asked questions

What's the simplest HTML contact form?

A <form> element with method="POST" and an action URL pointing to a form backend, three input fields (name, email, message) with name attributes, a honeypot field for spam protection, and a submit button. That is 12 lines of HTML total.

Can non-developers add a form?

Yes. Copy the HTML snippet from this guide, paste it into your website's HTML editor or CMS embed block, and replace YOUR_FORM_ID with the ID from your FormWit dashboard. No programming knowledge required beyond basic copy-paste.

Do I need a backend server?

No. FormWit is the backend. It receives form submissions, stores them, filters spam, and sends you email notifications. Your website just needs to serve the HTML form. This works on any hosting provider, including free static hosts like GitHub Pages and Netlify.

Want to skip the setup?

FormWit gives you a form endpoint in 60 seconds. Free plan, no credit card.

Create Free Form

Need a form fast?

Build one visually with our free HTML form generator — no coding required.

Try the Form Generator →

Build your simple form

Add a contact form to your site in 30 seconds. No backend code required.

Try FormWit Free