HTML forms

The HTML email input, explained.

An <input type="email"> asks the browser to check that the value looks like an email address before the form is sent, and gives phone users a keyboard with an @ key. Here is how it behaves, which attributes are worth using, and where its checks stop.

Updated 28 October 2026

The basic email input

HTML
<label for="email">Email</label>
<input id="email" type="email" name="email" autocomplete="email" required />
  • type="email" makes the browser refuse to submit a value that is not shaped like an address, and shows its own message.
  • required blocks an empty field. Without it, an empty email input is valid.
  • autocomplete="email" lets the browser offer the visitor’s saved address.
  • A visible label, linked with for and id, is what screen readers announce. A placeholder is not a label: it disappears as soon as someone types.
  • name is the key the value is sent under. Without a name the field is not sent at all.

What the browser checks, and what it misses

The check is about shape only. A value passes if it has a local part, an @ and a domain made of letters, digits, hyphens and dots. That means:

  • name@example.com passes, as you would expect.
  • name@localhost also passes, because a dot in the domain is not required.
  • name@example passes too, even though it is almost certainly a typo.
  • name example.com and @example.com fail.
  • Spaces at the start and end are removed before the check.

The browser never checks that the address exists or can receive mail, and anyone can skip the check by posting to your form directly. Treat it as a help for honest visitors, not as validation you can rely on.

Require a dot in the domain with pattern

If you want to catch name@example, add a pattern. It is checked on top of the email rules and must match the whole value. The title text is added to the browser’s message when the pattern fails.

HTML
<label for="work-email">Work email</label>
<input id="work-email" type="email" name="email" autocomplete="email" required
       pattern=".+@.+\..+"
       title="Use a full address, like name@company.com" />

Several addresses in one field

The multiple attribute accepts a comma-separated list, and each address is checked on its own.

HTML
<label for="cc">Also send a copy to</label>
<input id="cc" type="email" name="cc" multiple
       placeholder="ana@example.com, sam@example.com" />

Style an invalid email field

The :invalid selector matches an empty required field as soon as the page loads, which looks like an error before anyone has typed. :user-invalid waits until the visitor has interacted with the field, and is supported in current Chrome, Edge, Firefox and Safari.

CSS
/* :user-invalid waits until the visitor has interacted, so an empty form is not red on load */
input[type="email"]:user-invalid {
  border-color: #b42318;
  outline-color: #b42318;
}

Your own error message with JavaScript

The built-in message differs between browsers and languages. To use your own wording, set it with setCustomValidity while the value is wrong, and clear it when the value is fixed. validity.typeMismatch is true when the value is not shaped like an email address.

JavaScript
const input = document.querySelector('#email');
input.addEventListener('input', () => {
  if (input.validity.typeMismatch) {
    input.setCustomValidity('Enter an email address, like name@example.com.');
  } else {
    input.setCustomValidity(''); // an empty message marks the field valid again
  }
});

To turn the browser’s checks off for the whole form, for example because you validate in your own script, add novalidate to the <form>.

A form that sends

An email input on its own goes nowhere: the form needs an action that receives it. This one posts to Heartdove, which saves every message, emails you an alert and tracks it until it is delivered or bounces. Because the field is named email, the alert’s reply-to is set to the visitor’s address when it looks valid, so you can answer with one click.

contact.html
<form action="https://submit.heartdove.com/v1/submit" method="POST">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />

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

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

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

  <input type="checkbox" name="botcheck" tabindex="-1" autocomplete="off" style="display:none" />
  <button type="submit">Send message</button>
</form>

Replace YOUR_ACCESS_KEY with your form’s key from a free Heartdove form. The hidden botcheck field is a spam trap that people never see. To add dropdowns, checkboxes or a phone field, use the contact form generator.

Questions

Does type="email" check that the address is real?

No. It only checks the shape of the value. Whether the address exists, or whether mail to it is delivered, can only be found out by sending to it.

Why does name@localhost pass?

The HTML rules for email inputs do not require a dot in the domain, because addresses on local networks are valid. Add a pattern such as .+@.+\..+ if you want to require one.

How do I allow more than one email address?

Add the multiple attribute. Visitors can then enter a comma-separated list, and each address is checked on its own.

Is browser validation enough on its own?

No. It helps honest visitors fix typos, but anything can be posted to your form without a browser. Whatever receives the form has to treat every value as unchecked.

Never lose another enquiry.

Connect your first form in a few minutes. Your existing design stays exactly as it is.