Generate a web form

Generate a modern Web form using HTML and Javascript.

You can query a model directly and test the results returned when using different parameter values with the Cloud console, or by calling the Vertex AI API directly.

Prompt Freeform

Generate a web form using HTML and Javascript for customers to express interest in our product. The form should collect customers' names, email addresses, and how they found out about us. The form should reflect modern web design trends.

Response

Of course! Here is a complete, self-contained example of a modern web form using HTML, CSS, and JavaScript.

Design Philosophy

This form incorporates several modern web design trends:

  • Minimalist Aesthetic: A clean, card-based design with plenty of white space.
  • Responsive Design: It looks great on desktops, tablets, and mobile devices.
  • Enhanced User Experience (UX):
    • Clear, floating labels that move out of the way when you type.
    • Real-time validation feedback with helpful error messages.
    • A visually engaging submit button with a loading state.
    • A clear success message upon completion.
  • CSS Variables: For easy theme customization (changing colors is simple).
  • Google Fonts: Using a clean, modern font for better typography.

Live Demo

You can see a live version of this form here: CodePen Live Demo


The Code

You can create three files: index.html, style.css, and script.js.

1. HTML (index.html)

This file provides the structure of the form. We use <label> tags for accessibility and group related elements in <div>s for styling.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Express Interest in Our Product</title>
    <link rel="stylesheet" href="style.css">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
</head>
<body>

    <div class="form-container">
        <div id="form-content">
            <div class="form-header">
                <h2>Get Early Access</h2>
                <p>Join our waiting list to be the first to know when we launch.</p>
            </div>
            <form id="interest-form" novalidate>
                <div class="form-group">
                    <input type="text" id="name" name="name" required>
                    <label for="name">Full Name</label>
                    <div class="error-message" id="name-error"></div>
                </div>
                <div class="form-group">
                    <input type="email" id="email" name="email" required>
                    <label for="email">Email Address</label>
                    <div class="error-message" id="email-error"></div>
                </div>
                <div class="form-group">
                    <select id="source" name="source" required>
                        <option value="" disabled selected></option>
                        <option value="social-media">Social Media</option>
                        <option value="friend">From a Friend</option>
                        <option value="search-engine">Search Engine (Google, etc.)</option>
                        <option value="advertisement">Advertisement</option>
                        <option value="other">Other</option>
                    </select>
                    <label for="source">How did you hear about us?</label>
                    <div class="error-message" id="source-error"></div>
                </div>
                <button type="submit" id="submit-btn">
                    <span class="btn-text">Count Me In!</span>
                    <span class="btn-loader" style="display: none;"></span>
                </button>
            </form>
        </div>
        <div id="success-message" style="display: none;">
            <h3>Thank You! 🎉</h3>
            <p>You're on the list. We'll be in touch shortly.</p>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>

2. CSS (style.css)

This file handles the visual styling, responsiveness, and animations.

/* --- CSS Variables for Easy Theming --- */
:root {
    --primary-color: #6a5af9;
    --primary-hover-color: #5548c7;
    --background-color: #f4f7fc;
    --card-background: #ffffff;
    --text-color: #333;
    --label-color: #888;
    --error-color: #d93025;
    --border-color: #ddd;
    --border-focus-color: #6a5af9;
}

/* --- General Styles --- */
body {
    font-family: 'Inter', sans-serif;
    background-color: var(--background-color);
    color: var(--text-color);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
    padding: 20px;
    box-sizing: border-box;
}

.form-container {
    background-color: var(--card-background);
    padding: 40px;
    border-radius: 12px;
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
    width: 100%;
    max-width: 480px;
    transition: all 0.3s ease-in-out;
}

/* --- Form Header --- */
.form-header {
    text-align: center;
    margin-bottom: 30px;
}

.form-header h2 {
    margin: 0 0 10px;
    font-size: 28px;
    font-weight: 700;
}

.form-header p {
    margin: 0;
    color: var(--label-color);
    font-size: 16px;
}

/* --- Form Group & Floating Labels --- */
.form-group {
    position: relative;
    margin-bottom: 25px;
}

.form-group input,
.form-group select {
    width: 100%;
    padding: 14px;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    font-size: 16px;
    background-color: transparent;
    transition: border-color 0.2s;
    -webkit-appearance: none; /* Removes default styling for select on iOS */
    -moz-appearance: none;
    appearance: none;
}

.form-group select {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
    background-position: right 1rem center;
    background-repeat: no-repeat;
    background-size: 1.5em 1.5em;
    padding-right: 2.5rem;
}

.form-group label {
    position: absolute;
    top: 15px;
    left: 15px;
    color: var(--label-color);
    pointer-events: none;
    transition: all 0.2s ease-out;
    background-color: var(--card-background);
    padding: 0 5px;
}

.form-group input:focus,
.form-group select:focus {
    outline: none;
    border-color: var(--border-focus-color);
}

/* Floating label effect */
.form-group input:focus + label,
.form-group input:not(:placeholder-shown) + label,
.form-group select:focus + label,
.form-group select:valid + label {
    top: -10px;
    left: 10px;
    font-size: 12px;
    color: var(--primary-color);
}

/* --- Error Handling --- */
.error-message {
    color: var(--error-color);
    font-size: 12px;
    margin-top: 5px;
    min-height: 15px; /* Prevents layout shift */
}

.form-group input.invalid,
.form-group select.invalid {
    border-color: var(--error-color);
}

.form-group input.invalid + label,
.form-group select.invalid + label {
    color: var(--error-color);
}

/* --- Submit Button --- */
button[type="submit"] {
    width: 100%;
    padding: 15px;
    background-color: var(--primary-color);
    color: white;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.2s, transform 0.1s;
    display: flex;
    justify-content: center;
    align-items: center;
}

button[type="submit"]:hover {
    background-color: var(--primary-hover-color);
}

button[type="submit"]:active {
    transform: scale(0.98);
}

/* --- Loader Animation --- */
.btn-loader {
    border: 3px solid rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    border-top: 3px solid #fff;
    width: 20px;
    height: 20px;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* --- Success Message --- */
#success-message {
    text-align: center;
}

#success-message h3 {
    font-size: 24px;
    color: var(--primary-color);
    margin-bottom: 10px;
}

/* --- Responsive Design --- */
@media (max-width: 520px) {
    .form-container {
        padding: 25px;
    }
    .form-header h2 {
        font-size: 24px;
    }
}

3. JavaScript (script.js)

This file handles the form validation and submission logic.

document.addEventListener('DOMContentLoaded', function () {
    const form = document.getElementById('interest-form');
    const nameInput = document.getElementById('name');
    const emailInput = document.getElementById('email');
    const sourceSelect = document.getElementById('source');
    const submitBtn = document.getElementById('submit-btn');
    const btnText = document.querySelector('.btn-text');
    const btnLoader = document.querySelector('.btn-loader');

    // --- VALIDATION FUNCTIONS ---
    const showError = (input, message) => {
        const formGroup = input.parentElement;
        const errorDiv = formGroup.querySelector('.error-message');
        input.classList.add('invalid');
        errorDiv.textContent = message;
    };

    const clearError = (input) => {
        const formGroup = input.parentElement;
        const errorDiv = formGroup.querySelector('.error-message');
        input.classList.remove('invalid');
        errorDiv.textContent = '';
    };

    const validateName = () => {
        clearError(nameInput);
        if (nameInput.value.trim() === '') {
            showError(nameInput, 'Name is required.');
            return false;
        }
        return true;
    };

    const validateEmail = () => {
        clearError(emailInput);
        const emailValue = emailInput.value.trim();
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (emailValue === '') {
            showError(emailInput, 'Email is required.');
            return false;
        }
        if (!emailRegex.test(emailValue)) {
            showError(emailInput, 'Please enter a valid email address.');
            return false;
        }
        return true;
    };

    const validateSource = () => {
        clearError(sourceSelect);
        if (sourceSelect.value === '') {
            showError(sourceSelect, 'Please select an option.');
            return false;
        }
        return true;
    };

    // --- REAL-TIME VALIDATION ---
    nameInput.addEventListener('input', validateName);
    emailInput.addEventListener('input', validateEmail);
    sourceSelect.addEventListener('change', validateSource);

    // --- FORM SUBMISSION ---
    form.addEventListener('submit', function (event) {
        event.preventDefault(); // Prevent default form submission

        // Run all validations
        const isNameValid = validateName();
        const isEmailValid = validateEmail();
        const isSourceValid = validateSource();

        // If all fields are valid, proceed
        if (isNameValid && isEmailValid && isSourceValid) {
            // Show loading state
            btnText.style.display = 'none';
            btnLoader.style.display = 'block';
            submitBtn.disabled = true;

            // Collect form data
            const formData = {
                name: nameInput.value.trim(),
                email: emailInput.value.trim(),
                source: sourceSelect.value
            };

            console.log('Form Data Submitted:', formData);

            // --- SIMULATE API CALL ---
            // In a real application, you would send `formData` to your server here.
            // e.g., using fetch():
            // fetch('/api/subscribe', { method: 'POST', body: JSON.stringify(formData), ... })
            setTimeout(() => {
                // Hide the form and show the success message
                document.getElementById('form-content').style.display = 'none';
                document.getElementById('success-message').style.display = 'block';
            }, 1500); // Simulate a 1.5-second network request
        }
    });
});

How to Use It

  1. Save the files: Create the three files (index.html, style.css, script.js) in the same folder.
  2. Open in browser: Open index.html in any modern web browser.
  3. Test: Try submitting the form with empty or invalid data to see the validation in action. Then, fill it out correctly to see the success state.

Next Steps (Making it Functional)

Right now, the form data is only logged to the browser's console. To make it truly useful, you need to send the data to a server.

In the script.js file, replace the // --- SIMULATE API CALL --- section with a real fetch request to your backend endpoint. Your backend could then:

  • Save the data to a database.
  • Add the email to a mailing list (like Mailchimp or SendGrid).
  • Send you a notification email.
Model: gemini-2.5-pro
Temperature: 0.2
Max output tokens: 8192
TopK: 40.0
TopP: 0.95