Responsive HTML email contact form with email, message fields, and code symbols
Blog

How to Create a Simple HTML Email Contact Form with CSS

Build a responsive email contact form with HTML and CSS, then learn what is required to deliver a message. HTML creates the fields and CSS controls the layout; a server-side script such as PHP is needed to validate and send an email. The demo below runs entirely in your browser and does not transmit or store your message. Quick answer: Create semantic form fields with labels, use type="email" and required for built-in browser validation, style the form with responsive CSS, and submit it to a server endpoint. Never put mail credentials in front-end JavaScript.

Try the live demoDownload source code

Live HTML email form demo

Enter sample values and submit to see the front-end confirmation. This live preview is intentionally client-side: it does not send the form to an inbox. The downloadable project includes an example PHP endpoint that you can configure on your own PHP host.

1. Add accessible HTML form fields

Use a real <form>, visible labels, meaningful field names, and the correct input types. The sample includes first and last name, email, an optional phone number, and a message. Browser validation improves usability, but it is not a substitute for validating input on the server.

2. Style the form with responsive CSS

CSS creates a centered card, readable labels, clear focus states, and a two-column name row on wider screens. A media query stacks the name fields on narrow screens. The downloadable styles.css is scoped to this example page so its styles do not unintentionally change other pages.

3. Add a client-side demo response

The small JavaScript file intercepts submission only when the form has data-demo-mode="true". It uses browser validity checks, displays a status message, and resets the sample fields. Remove demo mode only when the form action points to a working server endpoint.

4. Send email with a server-side handler

A browser cannot securely send email by itself. In the included PHP example, replace the recipient and sender placeholders, host it on a server with PHP enabled, and configure reliable mail delivery. For production, use authenticated SMTP through a reputable provider, protect the endpoint from abuse, and serve the site over HTTPS. Do not expose SMTP passwords or API keys in HTML or JavaScript.

Validation and spam protection

  • Validate every field again on the server; users can bypass browser checks.
  • Keep input length limits and validate email addresses before sending.
  • Use rate limiting or a CAPTCHA alternative when spam becomes a problem; a honeypot alone is not sufficient security.
  • Use a fixed email subject and treat message content as untrusted input.
  • Collect only information you need and explain how contact details are used.

Frequently asked questions

Can HTML and CSS send an email?

No. HTML and CSS present the form. A server-side handler or a trusted form service must receive the submission and send the email.

Does the live demo send my message?

No. The embedded demo provides a local confirmation only. It does not transmit or save the information entered.

Can I use this form on WordPress?

Yes, but configure a supported form plugin or a server-side endpoint and test email delivery on your hosting. Do not paste PHP into a front-end HTML widget.

Download the complete example

The ZIP contains the standalone demo, responsive stylesheet, browser-only demo script, a configurable PHP handler, and setup notes. Configure the PHP mail recipient and delivery method before using it on a live site.
Accessible HTML contact form fields
<form class="contact-form" action="send.php" method="post">
  <div class="field-row">
    <label>First name
      <input name="first_name" autocomplete="given-name" maxlength="60" required>
    </label>
    <label>Last name
      <input name="last_name" autocomplete="family-name" maxlength="60" required>
    </label>
  </div>
  <label>Email address
    <input type="email" name="email" autocomplete="email" maxlength="254" required>
  </label>
  <label>Phone number (optional)
    <input type="tel" name="phone" autocomplete="tel" maxlength="30">
  </label>
  <label>Message
    <textarea name="message" rows="5" minlength="10" maxlength="3000" required></textarea>
  </label>
  <button type="submit">Send message</button>
</form>
Responsive contact form CSS
* { box-sizing: border-box; }
.contact-form { display: grid; gap: 16px; max-width: 620px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.contact-form label { display: grid; gap: 7px; font-weight: 650; }
.contact-form input, .contact-form textarea {
  width: 100%; min-width: 0; padding: 12px 14px;
  border: 1px solid #c9d5e6; border-radius: 10px;
  background: #fff; color: #15223b; font: inherit;
}
.contact-form input:focus, .contact-form textarea:focus {
  outline: 3px solid rgba(36, 89, 173, .16); border-color: #2459ad;
}
.contact-form textarea { resize: vertical; }
.contact-form button { justify-self: start; padding: 12px 20px; border: 0; border-radius: 10px; background: #2459ad; color: #fff; font: inherit; font-weight: 700; cursor: pointer; }
@media (max-width: 540px) { .field-row { grid-template-columns: 1fr; } }
Client-side demo behavior (JavaScript)
const form = document.querySelector(".contact-form");
const status = document.querySelector(".form-status");

form.addEventListener("submit", (event) => {
  if (form.dataset.demoMode !== "true") return;
  event.preventDefault();
  if (!form.reportValidity()) return;

  const data = new FormData(form);
  const name = `${data.get("first_name")} ${data.get("last_name")}`.trim();
  status.textContent = `Thanks, ${name}. This demo does not send email.`;
  form.reset();
});
Server-side PHP email handler
<?php
$recipient = 'you@example.com'; // Replace with your inbox.
$senderAddress = 'no-reply@yourdomain.com'; // Use your own domain.

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    exit('Method not allowed.');
}

$firstName = trim((string)($_POST['first_name'] ?? ''));
$lastName = trim((string)($_POST['last_name'] ?? ''));
$email = trim((string)($_POST['email'] ?? ''));
$message = trim((string)($_POST['message'] ?? ''));

if ($firstName === '' || $lastName === '' || !filter_var($email, FILTER_VALIDATE_EMAIL) || mb_strlen($message) < 10 || mb_strlen($message) > 3000) {
    http_response_code(400);
    exit('Please check the form fields.');
}

$subject = 'New contact form message';
$body = "Name: {$firstName} {$lastName}\nEmail: {$email}\n\n{$message}";
$headers = ['From' => $senderAddress, 'Reply-To' => $email, 'Content-Type' => 'text/plain; charset=UTF-8'];

if (!mail($recipient, $subject, $body, $headers)) {
    http_response_code(500);
    exit('Email could not be sent. Configure server mail or SMTP.');
}
header('Location: thank-you.html', true, 303);
exit;
?>