How To Build an HTML Contact Form

This page may contain links from our sponsors. Here’s how we make money.

A big challenge when coding an HTML contact form is choosing a reliable backend language. There are a ton of different options that we’ll cover today, including a couple of tutorials.

In one tutorial, I’ll explain how to build a contact form reliant on MailThis as a backend. You don’t need PHP or Python, or even a webserver! MailThis can take requests from any page with a properly structured form and deliver crisp e-mails in a jiffy.

Creating an HTML Contact Form

creating an HTML contact form
Download Source Code

Getting Started

MailThis is completely free to use and even has documentation on their website. I’ll be covering many core features, but one thing I won’t do is set up an email alias.

Since your e-mail address goes inside the POST form URL(ex:, it’s very easy for a spammer or spambot to examine your code and start spamming the address.

MailThis can provide a free alias that masks your real email in the form’s code. I would highly recommend doing this for every live project using MailThis.

To do so visit the homepage and set up your preferred e-mail with an alias username.

create an email alias

Next, we’ll create the form itself. You’ll notice MailThis provides a sample form, but I’ve coded my own with some extra features.

Building the Form

Since the exact syntax is very important, I’ve broken down my source into two blocks of code for explanation. Here’s the first part:

<form action="" method="post">

  <div class="inputblock">
    <label for="email">Email Address:</label>
    <input type="email" name="email" id="name" class="txt">

  <div class="inputblock">
    <label for="_subject">Subject</label>
    <div class="select-style">
    <select name="_subject">
      <option value="General Inquiry">General Inquiry</option>
      <option value="Support">Support</option>
      <option value="Advertising">Advertising</option>
      <option value="Press or Media">Press or Media</option>
  <div class="inputblock">
    <label for="message">Message:</label>
    <textarea cols="40" rows="8" name="message" class="txt"></textarea>

The form action attribute must be set to this specific syntax, always using a POST command. Simply replace the email address with your own(or specifically your new alias).

Each input field has a naming convention that must be maintained. An Input with the name email holds the sender’s e-mail(the “from” field).

An input with the name _subject contains the message subject. MailThis suggests creating a hidden input with this value, but I’ve taken it one step further with a dropdown menu. This allows users to select a subject from a predefined list of your choosing.

The subject itself can also be set manually or added to an input text field instead. No matter what you choose just make sure the field’s value attribute contains the exact text you want for the e-mail subject line.

Then finally a textarea with the name message contains the body message. All HTML characters still remain so users can e-mail you hyperlinks by writing HTML code.

  <input type="hidden" name="_replyto" value="%email">
  <input type="hidden" name="_valid[email]" value="valid_email">
  <input type="hidden" name="_valid[message]" value="min_length[10]">
  <input type="hidden" name="_after" value="">
  <div class="inputblock">
    <input type="submit" class="submit-btn" value="Send Message">

Here’s the second half of the form. The only other visible input is a submit button which actually sends the form data to MailThis’ server.

All other input types are hidden because they don’t require user input. These are actually rules for how each form input should behave, also called validation fields in the MailThis documentation.

validation field mailthis table

Visit the MailThis webpage to find a table full of these validation fields with proper syntax. My demo has 3 active validation fields with an optional 4th you can use in your own projects.

The first field _replyto sets the e-mail’s replyto address. Most people want to reply directly to the person who sent the e-mail, and we can pull this info directly from their email input with the syntax %email.

Next I have two fields with the name _valid using suffix codes for which inputs are being targeted. For example my first validity check targets the input with a name of email. The value check is valid_email which should be self-explanatory.

You don’t have to write a single line of JavaScript or anything to get these validations working. MailThis handles everything with pre-built validation checks.

I’m using a similar check on the message field with a value of min_length[10]. Again hopefully self-explanatory, this forces users to enter at least 10 characters into their e-mail message before it’ll be considered valid.

Lastly I have a hidden input stored in an HTML comment. The name is _after which behaves as a redirect field. Instead of loading the default MailThis sent page, you can instead devise your own “email sent successfully” page.

The benefit is that you’ll keep visitors on your domain rather than redirecting them over to MailThis. It’s not necessary for the sake of my demo, but in a real-world project it could be very useful.

To find more of these validation checks visit the MailThis documentation to see if there’s anything else you could implement.

Final E-mail Confirmation

Once the form is complete you can try sending an e-mail to yourself, but you’ll receive a message like this:

verify mailthis email

It’s just a security measure to prevent spam and only happens once.

An e-mail will be sent to the form address with a confirmation link. Click the link and you’ll be all set.

success verified email message

When you’re doing this for a client’s website be sure to guide them through this initial setup. It only needs to be done once and might be confusing to people who wouldn’t know what to do when encountering such a message(webmasters or end-users).

mailthis custom api form

Next, Coding a Guided Registration Form with jQuery:

In this tutorial, I want to demonstrate how we can build such an interface with CSS and jQuery. We can embed hidden form tips which only display when the user has focused on a particular field. These hints can be used to denote syntaxes, such as the required length of usernames or passwords. But it’s a great usability tactic that livens up even the dullest websites.

Guided Registration Form Preview

Building the Webpage

We can start by coding just the standard HTML5 markup for the registration form. In my header, I’ve got a reference to an external stylesheet styles.css along with a unique JavaScript file regform.js. We will use both of these to add our custom code, along with the most recent copy of jQuery.

<link rel="stylesheet" type="text/css" media="all" href="styles.css">
<script type="text/javascript" language="javascript" src=""></script>
<script type="text/javascript" language="javascript" src="regform.js"></script>

To keep the layout simple I’ve placed the whole form inside a wrapper div with the margin: 0 auto; property setup. The form itself doesn’t tie into any backend – the action attribute points back to index.html passing data via POST.

<div id="form-container">
	<form id="register" name="register" action="index.html" method="post">
	  <h3>100% free, and account registration only takes 60 seconds!</h3>

	  <div class="row">
	    <label for="username">Enter a Username ?</label>
	    <input type="text" id="username" name="username" class="reg-input tiny" autocomplete="off" tabindex="1">
	    <div class="note"><span id="note-username">Minimum of 3 characters to a max of 20.</span></div>

To encapsulate the row areas I’ve divided the form into separate div classes. Each row contains a small label along with the input field on the right-hand side. After this, I’m using another div with the class .note to hide a block element of form hints.

I’m using a number of additional attributes in the HTML to make the form easier for mobile users. autocomplete=”off” turns off the typical browser suggestion history which can be quite annoying at times. Also, the tabindex attribute is set up +1 for each of the input fields in sequential order.

Stylin’ with CSS

The attached stylesheet is small but very manageable for this interface. First I’m using some really simple resets to remove margins, padding, and modulate font sizes between all browsers.

* { margin: 0; padding: 0; outline: none; }
body { font-size: 62.5%; height: 101%; background: #edf8ef; padding-bottom: 45px; font-family: Arial, Tahoma, sans-serif; }

img { border: 0; }

h2 { font-size: 1.9em; color: #5b83b4; margin-bottom: 12px; }
h3 { font-size: 1.65em; line-height: 1.8em; font-weight: normal; letter-spacing: -0.07em; color: #849669; margin-bottom: 20px; }
p { font-size: 1.2em; line-height: 1.3em; margin-bottom: 10px; }

#wrapper { width: 850px; margin: 0 auto; margin-top: 25px; background: #fff; border-radius: 6px; -webkit-border-radius: 6px; -moz-border-radius: 6px; padding: 20px 14px; }

#form-container { background: #d6f4cb; padding: 6px 15px; }

The labels and inputs inside each row are positioned carefully using inline-block. This will keep their display property with margins/padding while still holding the two elements next to each other. In the next block of code, you’ll see I also set up 2 different classes for the text fields – one regular length and the other that’s a bit shorter. We can target both of these in jQuery later on.

.row { display: block; margin-bottom: 10px;  }

.row label { display: inline-block; font-size: 1.3em; color: #78815a; width: 220px; font-family: Georgia, Times New Roman, serif; text-shadow: 1px 1px 0px #f1f9ea; }
.row .reg-input { padding: 4px 8px; width: 500px; font-size: 1.2em; border: 1px solid #c0c0c0; color: #979797; margin-bottom: 8px; }
.row .reg-input:focus {
color: #818181;
border-color: #b3c2db;
box-shadow: 0 0 7px rgba(150, 175, 210, 0.8);
-moz-box-shadow: 0 0 7px rgba(150, 175, 210, 0.8);
-webkit-box-shadow: 0 0 7px rgba(150, 175, 210, 0.8);

.row select, .row option { color: #979797; }

.row .reg-input.tiny { width: 265px; }

I’m using some additional effects on the focus event for each input. CSS3 includes dynamic box-shadow effects which look great as you tab through the different inputs. For the select menus, I’m trying to keep them much simpler so they just float next to each other.

Custom Buttons

The only other interesting bit of CSS code is designing the submit button. Thanks to such wide browser support we can build CSS3 gradients which require no images and can scale properly regardless of screen resolution. In our form design, I’ve stuck with the green color scheme but it’s so easy to change the hexadecimal values tuned with your own layout.

form #submit {
	display: block;
	outline: none;
	cursor: pointer;
	text-align: center;
	text-decoration: none;
	margin-top: 20px;
	margin-bottom: 12px;
	font: 14px/100% Arial, Helvetica, sans-serif;
	padding: .5em 2em .55em;
	text-shadow: 0 1px 1px rgba(0,0,0,.3);
	-webkit-border-radius: .5em;
	-moz-border-radius: .5em;
	border-radius: .5em;
	-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .4);
	-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, .4);
	box-shadow: 0 1px 2px rgba(0, 0, 0, .4);
	color: #fef4e9;
	border: solid 1px #99d235;
	background: #9beb46;
	background: -webkit-gradient(linear, left top, left bottom, from(#8efa1a), to(#86c944));
	background: -moz-linear-gradient(top,  #8efa1a,  #86c944);
	filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#8efa1a', endColorstr='#86c944');

form #submit:hover {
	background: #8ce028;
	background: -webkit-gradient(linear, left top, left bottom, from(#9be72f), to(#93db4d));
	background: -moz-linear-gradient(top,  #9be72f,  #93db4d);
	filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#9be72f', endColorstr='#93db4d');

form #submit:active {
	color: #ddf9ba;
	border-color: #98b95d;
	background: -webkit-gradient(linear, left top, left bottom, from(#9dcc6a), to(#7bac41));
	background: -moz-linear-gradient(top,  #9dcc6a,  #7bac41);
	filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#9dcc6a', endColorstr='#7bac41');

One last note in the CSS file is how we’ve set up the small icons appearing on each note element. You can update these to display an error or success checkmark as the user validates each field. For this demo, it’s a lot easier just focusing on the informational fields without full validity. But the different classes are already included within the stylesheet if needed.

Dynamic jQuery

For the last part of our model let’s look into the regform.js file and see how to code these hints. I’ll break down the block into two sections for the focus and blur event handlers.

$(document).ready(function() {
  $(".reg-input, .sel-input").focus(function() {
    var theinput = $(this).attr("id");
	var thenote  = "#note-"+theinput;


The selector I’m using will target both the regular inputs and the select menus. I haven’t included anything for the birthday section because it would change on each of the different day/month/year selections.

Each note has an internal span ID in the form of #note-ID where the ID value is the associated input field’s name. This is the value we set up in the variable thenote and we can use this to quickly select the internal span to fade in and out.

	var theinput = $(this).attr("id");
	var thenote  = "#note-"+theinput;
	var currval  = $(this).val();

	if(currval == "" || currval == " ") {
	} else {
	  // we do nothin

For the blur event handler, I’ve added a bit more logic to the equation. The new variable curved gets the value of the currently targeted input before the user removes their focus. We can then check if the form is totally blank and re-hide the info field. Otherwise, if the field has value we can keep the text displayed as a cautious reminder(makes proofreading handy!).

And that should be all we need to get this running! The JavaScript actually isn’t too confusing but for new scripters, it may take some references to the jQuery docs. Feel free to test out the live demo and download my source code which you can play around with on your own. 

Download Source Code

Now, Let’s Cover Other Resources:

There are a number of resources available that have been created to make it easier for designers, developers, and website owners to quickly and easily create attractive, usable forms without the need to code. In this post we’ll look at some of the best options available.

The resources featured in this post include some free options and a number of paid options. Most of the paid options include a lot of features, and in many cases the ability to integrate your forms with PayPal or other payment gateways.


With Formstack you can create standard contact forms, set up surveys, accept donations, manage event registrations, and more. The form builder will allow you to easily create forms without the need for coding, and Formstack helps you to manage the data that is collected through the forms (store in a database, export to Excel, or use the API). You can even use a payment integration feature. The paid plans range from $39 – $249 per month.



Wufoo’s HTML form builder makes it easy to create contact forms, surveys, registrations, and online payments forms. You can choose from an existing template or customize it to meet your needs. Wufoo also includes some useful reporting tools to help you analyze the data that is being collected. A free plan is available that allows for 1 user, 3 forms, 3 reports, 10 fields, and 100 entries per month (with some limited features). Paid plans range from $14.95 – $69.95 per month.



FormSite has over 100 pre-built forms that can easily be customized to meet your own needs. You can create contact forms, surveys, registration forms, order forms, and more. There is a free account available that allows you to manage 5 forms and 10 submissions per month. The lowest-priced ad-free plan costs $24.95 per month.



MachForm helps you to create PHP forms without the need to code. It is a self-hosted solution option that stores all form submissions in a MySQL database. A single-site license costs $59 and an unlimited license costs $249.


Form Assembly

Form Assembly allows you to create a wide variety of forms, including contact forms, registration forms, and order forms. There is a free 14 day trial that will allow you to try out the service.

form assembly

WordPress Plugin Form Options:

For WordPress users and developers there are a number of plugins that will help you to create forms. Here is a look at some of the best.

Gravity Forms

Gravity Forms is a premium plugin for WordPress ($39 for a single-site license) that makes it quick and easy to create forms for a variety of purposes. You can use the forms to create posts (for user-submitted content), create autoresponders, and you can manage form submissions through the WordPress dashboard.

gravity forms

Contact Form 7

Contact Form 7 is a very popular plugin and is a great choice for creating standard contact forms. It’s fairly easy to set up and create your own forms, and to insert them into a post or page. You can also customize the emails that you’ll receive when a visitor completes the form.

contact form 7

Fast and Secure Contact Form

Fast and Secure Contact Form will allow you to set up general contact forms and protect them from spammers with CAPTCHAs and Akismet support.

fast and secure contact form
Get the Free Resources Bundle