Free Contact Form HTML & PHP Templates

We've got everything you need for adding a contact form to your website. The copy and paste code for our contact form includes the PHP backend and MySQL database schema - so you can add the messages straight into your database (for safe keeping in case anything goes wrong with the emails), and also send out the message as an email to yourself as soon as a user sends one.

If you need any help at all with getting it up and running on your website (eg. Wordpress problems) just contact us! Depending on what you're after, we might help you out for free, or at an extremely discounted rate.

Get In Touch

Fill out the form below and we'll get back to you shortly

👤
Please enter your name
✉️
Please enter a valid email
📞
Please enter your message
Thank you! Your message has been sent successfully.

📋 HTML Code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Contact Form</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        .container {
            max-width: 600px;
            width: 100%;
        }
        
        .contact-form {
            background: rgba(255, 255, 255, 0.95);
            border-radius: 20px;
            padding: 40px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
        }
        
        .form-header {
            text-align: center;
            margin-bottom: 30px;
        }
        
        .form-header h2 {
            color: #333;
            font-size: 2rem;
            margin-bottom: 10px;
        }
        
        .form-group {
            margin-bottom: 25px;
        }
        
        .form-group label {
            display: block;
            margin-bottom: 8px;
            color: #333;
            font-weight: 600;
        }
        
        .form-group input, .form-group textarea {
            width: 100%;
            padding: 14px 18px;
            border: 2px solid #e0e0e0;
            border-radius: 10px;
            font-size: 1rem;
            transition: all 0.3s ease;
        }
        
        .form-group input:focus, .form-group textarea:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
        }
        
        .submit-btn {
            width: 100%;
            padding: 16px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 10px;
            font-size: 1.1rem;
            cursor: pointer;
            transition: transform 0.3s ease;
        }
        
        .submit-btn:hover {
            transform: translateY(-2px);
        }

        .form-header {
            text-align: center;
            margin-bottom: 30px;
        }

        .form-header h2 {
            color: #333;
            font-size: 2rem;
            margin-bottom: 10px;
        }

        .form-header p {
            color: #666;
        }

        .form-group {
            margin-bottom: 25px;
        }

        .form-group label {
            display: block;
            margin-bottom: 8px;
            color: #333;
            font-weight: 600;
            font-size: 0.95rem;
        }

        .form-group input,
        .form-group textarea {
            width: 100%;
            padding: 14px 18px 14px 50px;
            border: 2px solid #e0e0e0;
            border-radius: 10px;
            font-size: 1rem;
            font-family: inherit;
            transition: all 0.3s ease;
            background: white;
        }

        .input-wrapper {
            position: relative;
        }

        .input-icon {
            position: absolute;
            left: 18px;
            top: 50%;
            transform: translateY(-50%);
            color: #999;
            font-size: 1.2rem;
            transition: color 0.3s ease;
        }

        .input-wrapper input:focus ~ .input-icon,
        .input-wrapper textarea:focus ~ .input-icon {
            color: #667eea;
        }

        .form-group input:focus,
        .form-group textarea:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
        }

        .form-group input::placeholder,
        .form-group textarea::placeholder {
            color: #aaa;
        }

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

        .form-group input.error,
        .form-group textarea.error {
            border-color: #e74c3c;
        }

        .error-message {
            color: #e74c3c;
            font-size: 0.85rem;
            margin-top: 5px;
            display: none;
        }

        .submit-btn {
            width: 100%;
            padding: 16px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 10px;
            font-size: 1.1rem;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .submit-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
        }

        .submit-btn:active {
            transform: translateY(0);
        }

        .submit-btn:hover span:last-child {
            transform: translateX(4px);
            display: inline-block;
        }

        .submit-btn span {
            transition: transform 0.3s ease;
        }

        .success-message {
            background: #2ecc71;
            color: white;
            padding: 15px;
            border-radius: 10px;
            margin-bottom: 20px;
            display: none;
        }
    </style>
</head>
<body>
    <div class="contact-form">
    <div class="form-header">
        <h2>Get In Touch</h2>
        <p>Fill out the form below and we'll get back to you shortly</p>
    </div>
    
    <form id="contactForm" method="POST" action="process_contact.php">
        <div class="form-group">
            <label for="name">Full Name *</label>
            <div class="input-wrapper">
                <input type="text" id="name" name="name" placeholder="John Doe" required>
                <span class="input-icon">👤</span>
            </div>
            <span class="error-message" id="nameError">Please enter your name</span>
        </div>
        
        <div class="form-group">
            <label for="email">Email Address *</label>
            <div class="input-wrapper">
                <input type="email" id="email" name="email" placeholder="john@example.com" required>
                <span class="input-icon">✉️</span>
            </div>
            <span class="error-message" id="emailError">Please enter a valid email</span>
        </div>
        
        <div class="form-group">
            <label for="phone">Phone Number</label>
            <div class="input-wrapper">
                <input type="tel" id="phone" name="phone" placeholder="0400 000 000">
                <span class="input-icon">📞</span>
            </div>
        </div>
        
        <div class="form-group">
            <label for="message">Message *</label>
            <div class="input-wrapper">
                <textarea id="message" name="message" placeholder="Tell us more about your inquiry..." required></textarea>
            </div>
            <span class="error-message" id="messageError">Please enter your message</span>
        </div>
        
        <button type="submit" class="submit-btn">
            Send Message
            <span style="margin-left: 8px;"></span>
        </button>
    </form>
    
    <div class="success-message" id="successMessage">
        Thank you! Your message has been sent successfully.
    </div>
</div>

<script>
document.getElementById('contactForm').addEventListener('submit', function(e) {
    e.preventDefault();
    
    // Clear previous errors
    document.querySelectorAll('.error-message').forEach(el => el.style.display = 'none');
    document.querySelectorAll('.error').forEach(el => el.classList.remove('error'));
    
    // Validate form
    let isValid = true;
    const name = document.getElementById('name');
    const email = document.getElementById('email');
    const message = document.getElementById('message');
    
    if (!name.value.trim()) {
        name.classList.add('error');
        document.getElementById('nameError').style.display = 'block';
        isValid = false;
    }
    
    if (!email.value.trim() || !email.value.includes('@')) {
        email.classList.add('error');
        document.getElementById('emailError').style.display = 'block';
        isValid = false;
    }
    
    if (!message.value.trim()) {
        message.classList.add('error');
        document.getElementById('messageError').style.display = 'block';
        isValid = false;
    }
    
    if (isValid) {
        // Submit form via AJAX
        const formData = new FormData(this);
        
        fetch('process_contact.php', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                document.getElementById('successMessage').style.display = 'block';
                this.reset();
                setTimeout(() => {
                    document.getElementById('successMessage').style.display = 'none';
                }, 5000);
            }
        })
        .catch(error => console.error('Error:', error));
    }
});
</script>
</body>
</html>

Now you'll need to create another simple PHP page in the same directory as your contact form.

Call this process_contact.php. In this page, we're validating the information sent over, storing it in the database, and also sending out an email to ourselves.

If you need the database schema, you can also copy that across.

🐘 process_contact.php

<?php
// Set response header to JSON
header('Content-Type: application/json');

// Database configuration
define('DB_HOST', 'localhost');
define('DB_USER', 'your_database_user');
define('DB_PASS', 'your_database_password');
define('DB_NAME', 'your_database_name');

// Email configuration
define('ADMIN_EMAIL', 'your-email@example.com'); // Where to send the contact form
define('FROM_EMAIL', 'noreply@yourdomain.com'); // From address
define('SITE_NAME', 'Your Website Name');

// Response array
$response = ['success' => false, 'message' => ''];

// Check if form was submitted via POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    $response['message'] = 'Invalid request method';
    echo json_encode($response);
    exit;
}

// Sanitize and validate input
function sanitize_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}

// Get and sanitize form data
$name = isset($_POST['name']) ? sanitize_input($_POST['name']) : '';
$email = isset($_POST['email']) ? sanitize_input($_POST['email']) : '';
$phone = isset($_POST['phone']) ? sanitize_input($_POST['phone']) : '';
$message = isset($_POST['message']) ? sanitize_input($_POST['message']) : '';

// Validate required fields
if (empty($name) || empty($email) || empty($message)) {
    $response['message'] = 'Please fill in all required fields';
    echo json_encode($response);
    exit;
}

// Validate email format
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $response['message'] = 'Invalid email address';
    echo json_encode($response);
    exit;
}

// --- DATABASE STORAGE ---
try {
    // Create database connection
    $conn = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASS);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // Prepare SQL statement
    $sql = "INSERT INTO contact_submissions (name, email, phone, message, ip_address, submitted_at) 
            VALUES (:name, :email, :phone, :message, :ip, NOW())";
    
    $stmt = $conn->prepare($sql);
    
    // Bind parameters
    $stmt->bindParam(':name', $name);
    $stmt->bindParam(':email', $email);
    $stmt->bindParam(':phone', $phone);
    $stmt->bindParam(':message', $message);
    $ip_address = $_SERVER['REMOTE_ADDR'];
    $stmt->bindParam(':ip', $ip_address);
    
    // Execute the statement
    $stmt->execute();
    
    $db_success = true;
} catch(PDOException $e) {
    $db_success = false;
    error_log("Database Error: " . $e->getMessage());
}

// --- EMAIL SENDING ---
$email_success = false;

// Prepare email
$to = ADMIN_EMAIL;
$email_subject = "New Contact Form Submission";

// Create email body
$email_body = "You have received a new message from your contact form.\n\n";
$email_body .= "Name: $name\n";
$email_body .= "Email: $email\n";
$email_body .= "Phone: $phone\n";
$email_body .= "Message:\n$message\n\n";
$email_body .= "---\n";
$email_body .= "Submitted from: " . $_SERVER['REMOTE_ADDR'] . "\n";
$email_body .= "Date: " . date('Y-m-d H:i:s') . "\n";

// Email headers
$headers = "From: " . SITE_NAME . " <" . FROM_EMAIL . ">\r\n";
$headers .= "Reply-To: $email\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();

// Send email
if (mail($to, $email_subject, $email_body, $headers)) {
    $email_success = true;
}

// --- PREPARE RESPONSE ---
if ($db_success || $email_success) {
    $response['success'] = true;
    $response['message'] = 'Thank you! Your message has been received.';
} else {
    $response['message'] = 'Sorry, there was an error processing your request. Please try again later.';
}

echo json_encode($response);

// Close database connection
$conn = null;
?>

🗄️ database_schema.sql

CREATE TABLE IF NOT EXISTS `contact_submissions` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NOT NULL,
  `email` VARCHAR(255) NOT NULL,
  `phone` VARCHAR(50) DEFAULT NULL,
  `message` TEXT NOT NULL,
  `ip_address` VARCHAR(45) DEFAULT NULL,
  `submitted_at` DATETIME NOT NULL,
  `status` ENUM('new','read','replied','archived') DEFAULT 'new',
  PRIMARY KEY (`id`),
  KEY `email` (`email`),
  KEY `submitted_at` (`submitted_at`),
  KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- Optional: Create an index for faster searching
CREATE INDEX idx_name ON contact_submissions(name);
CREATE INDEX idx_date_status ON contact_submissions(submitted_at, status);

-- Optional: Create a view for unread messages
CREATE VIEW unread_messages AS
SELECT id, name, email, submitted_at
FROM contact_submissions
WHERE status = 'new'
ORDER BY submitted_at DESC;

Free HTML Contact Form Template - Download Now

This free contact form HTML template is perfect for websites, portfolios, and business pages. Our responsive contact form includes a complete PHP backend for sending emails and storing submissions in a MySQL database. The form features modern design, client-side validation, and is fully mobile-responsive.

Features include: Responsive HTML5 design, PHP email functionality, MySQL database storage, client-side validation, modern gradient styling, and easy customization. Download this free contact form template and integrate it into your website today!