DEV Community

Cover image for Building a Premium Multi-Step Form with Animations
Gladiators Battle
Gladiators Battle

Posted on

Building a Premium Multi-Step Form with Animations

In this tutorial, we'll walk through creating a premium, interactive multi-step form with smooth animations and client-side validation using HTML, CSS, and JavaScript. This form provides an enhanced user experience and looks like something straight out of 2025!

Live Demo: https://codepen.io/HanGPIIIErr/pen/ZYzbrqW

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Project Structure
  4. HTML Markup
  5. Styling with CSS
  6. Adding Interactivity with JavaScript
  7. Conclusion

1.Introduction

Multi-step forms are an excellent way to enhance user experience by breaking down lengthy forms into manageable sections. In this tutorial, we'll create a five-step form that includes:

  • Personal Information
  • Preferences
  • Image Upload
  • Comments
  • Summary and Submission

We'll add smooth animations between steps and validate user inputs to ensure data integrity.

Prerequisites

Basic understanding of HTML, CSS, and JavaScript
Familiarity with form elements and event handling in JavaScript

Project Structure

We'll have three main files:

index.html โ€” The HTML structure
style.css โ€” The styling for our form
script.js โ€” The JavaScript to handle form interactions
Let's start by setting up our HTML file.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Premium Multi-Step Form</title>
    <link href="https://fonts.googleapis.com/css?family=Poppins:300,400,600&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <form id="multi-step-form">
        <!-- Step 1 -->
        <div class="form-step active">
            <div class="step-header">Step 1 of 5</div>
            <h2>Personal Information</h2>
            <label for="name">Name:</label>
            <input type="text" id="name" name="name" required minlength="2">
            <label for="email">Email:</label>
            <input type="email" id="email" name="email" required>
            <div class="buttons">
                <button type="button" class="next-step">Next</button>
            </div>
        </div>
        <!-- Step 2 -->
        <div class="form-step">
            <div class="step-header">Step 2 of 5</div>
            <h2>Preferences</h2>
            <label><input type="checkbox" name="pref" value="Option 1"> Option 1</label>
            <label><input type="checkbox" name="pref" value="Option 2"> Option 2</label>
            <label><input type="checkbox" name="pref" value="Option 3"> Option 3</label>
            <div class="buttons">
                <button type="button" class="prev-step">Previous</button>
                <button type="button" class="next-step">Next</button>
            </div>
        </div>
        <!-- Step 3 -->
        <div class="form-step">
            <div class="step-header">Step 3 of 5</div>
            <h2>Upload an Image</h2>
            <label for="image">Choose an image:</label>
            <input type="file" id="image" name="image" accept="image/*">
            <div class="buttons">
                <button type="button" class="prev-step">Previous</button>
                <button type="button" class="next-step">Next</button>
            </div>
        </div>
        <!-- Step 4 -->
        <div class="form-step">
            <div class="step-header">Step 4 of 5</div>
            <h2>Comments</h2>
            <label for="comments">Comments (max 200 characters):</label>
            <textarea id="comments" name="comments" maxlength="200"></textarea>
            <div class="buttons">
                <button type="button" class="prev-step">Previous</button>
                <button type="button" class="next-step">Next</button>
            </div>
        </div>
        <!-- Step 5 -->
        <div class="form-step">
            <div class="step-header">Step 5 of 5</div>
            <h2>Summary</h2>
            <div id="summary"></div>
            <div class="buttons">
                <button type="button" class="prev-step">Previous</button>
                <button type="submit">Submit</button>
            </div>
        </div>
    </form>
    <script src="script.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Explanation

  • Form Steps: Each step is wrapped in a div with the class form-step.
  • Active Class: The first step has the class active to display it initially.
  • Navigation Buttons: Each step (except the first and last) has "Previous" and "Next" buttons.
  • Summary Section: The last step displays a summary of the entered information.

Styling with CSS

Now, let's style our form to give it that premium feel.

/* style.css */

body {
    font-family: 'Poppins', sans-serif;
    background: linear-gradient(135deg, #1abc9c, #16a085);
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    overflow: hidden;
}

form {
    width: 90%;
    max-width: 600px;
    background: rgba(255, 255, 255, 0.95);
    padding: 3em;
    border-radius: 20px;
    box-shadow: 0 15px 25px rgba(0, 0, 0, 0.2);
    backdrop-filter: blur(10px);
    position: relative;
    overflow: hidden;
}

.form-step {
    position: absolute;
    width: 100%;
    opacity: 0;
    transform: scale(0.8) translateY(50px);
    transition: all 0.5s ease;
}

.form-step.active {
    opacity: 1;
    transform: scale(1) translateY(0);
    position: relative;
}

.step-header {
    position: absolute;
    top: -30px;
    right: 30px;
    background: #16a085;
    color: #fff;
    padding: 0.5em 1em;
    border-radius: 30px;
    font-weight: 600;
    animation: slideIn 0.5s forwards;
}

h2 {
    margin-bottom: 1em;
    color: #333;
    font-weight: 600;
    text-align: center;
    animation: fadeInDown 0.5s ease-in-out;
}

label {
    display: block;
    margin-top: 1em;
    color: #555;
    font-weight: 500;
    animation: fadeInUp 0.5s ease-in-out;
}

input[type="text"],
input[type="email"],
input[type="file"],
textarea {
    width: 100%;
    padding: 0.75em 1em;
    margin-top: 0.5em;
    border: 2px solid #ddd;
    border-radius: 10px;
    font-size: 1em;
    outline: none;
    transition: border-color 0.3s;
    animation: fadeInUp 0.5s ease-in-out;
}

input:focus,
textarea:focus {
    border-color: #1abc9c;
}

input[type="checkbox"] {
    margin-right: 0.5em;
}

.buttons {
    display: flex;
    justify-content: space-between;
    margin-top: 2em;
    animation: fadeInUp 0.5s ease-in-out;
}

button {
    padding: 0.75em 2em;
    border: none;
    border-radius: 30px;
    cursor: pointer;
    font-size: 1em;
    font-weight: 600;
    transition: background 0.3s, transform 0.3s, box-shadow 0.3s;
}

.next-step,
.prev-step {
    background: #1abc9c;
    color: #fff;
}

.next-step:hover,
.prev-step:hover {
    background: #16a085;
    transform: translateY(-3px);
    box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1);
}

button[type="submit"] {
    background: #e74c3c;
    color: #fff;
    margin-left: auto;
}

button[type="submit"]:hover {
    background: #c0392b;
    transform: translateY(-3px);
    box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1);
}

#summary p {
    margin: 1em 0;
    color: #333;
    font-weight: 500;
    animation: fadeInUp 0.5s ease-in-out;
}

/* Animations */
@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes fadeInDown {
    from {
        opacity: 0;
        transform: translateY(-30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateX(30px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation

  • Background Gradient: A smooth gradient provides a modern feel.
  • Form Styling: We use backdrop-filter for a glassmorphism effect.
  • Transitions and Animations: Smooth transitions and keyframe animations enhance interactivity.
  • Button Effects: Hover effects with slight movement and shadow for depth.
  • Adding Interactivity with JavaScript

Let's make our form functional.

document.addEventListener('DOMContentLoaded', function() {
    const form = document.getElementById('multi-step-form');
    const steps = document.querySelectorAll('.form-step');
    const nextBtns = document.querySelectorAll('.next-step');
    const prevBtns = document.querySelectorAll('.prev-step');
    const summary = document.getElementById('summary');
    let currentStep = 0;

    nextBtns.forEach(btn => {
        btn.addEventListener('click', () => {
            if (validateStep()) {
                steps[currentStep].classList.remove('active');
                currentStep++;
                if (currentStep < steps.length) {
                    steps[currentStep].classList.add('active');
                }
                if (currentStep === steps.length - 1) {
                    displaySummary();
                }
            }
        });
    });

    prevBtns.forEach(btn => {
        btn.addEventListener('click', () => {
            steps[currentStep].classList.remove('active');
            currentStep--;
            steps[currentStep].classList.add('active');
        });
    });

    form.addEventListener('submit', (e) => {
        e.preventDefault();
        alert('Form successfully submitted!');
        form.reset();
        steps[currentStep].classList.remove('active');
        currentStep = 0;
        steps[currentStep].classList.add('active');
    });

    function validateStep() {
        let stepIsValid = true;
        const currentInputs = steps[currentStep].querySelectorAll('input, textarea');
        currentInputs.forEach(input => {
            if (!input.checkValidity()) {
                input.reportValidity();
                stepIsValid = false;
            }
        });
        return stepIsValid;
    }

    function displaySummary() {
        const name = document.getElementById('name').value || 'N/A';
        const email = document.getElementById('email').value || 'N/A';
        const prefs = Array.from(document.querySelectorAll('input[name="pref"]:checked')).map(el => el.value).join(', ') || 'None';
        const comments = document.getElementById('comments').value || 'None';

        summary.innerHTML = `
            <p><strong>Name:</strong> ${name}</p>
            <p><strong>Email:</strong> ${email}</p>
            <p><strong>Preferences:</strong> ${prefs}</p>
            <p><strong>Comments:</strong> ${comments}</p>
        `;
    }

    // Initialize steps
    steps.forEach((step, index) => {
        if (index !== currentStep) {
            step.classList.remove('active');
        } else {
            step.classList.add('active');
        }
    });
});
Enter fullscreen mode Exit fullscreen mode

Explanation

  • Event Listeners: For "Next" and "Previous" buttons to navigate between steps.
  • Validation: validateStep() ensures required fields are filled.
  • Summary Display: displaySummary() compiles the entered data for the user to review.
  • Form Submission: On submission, the form resets and returns to the first step.

๐ŸŒŒ Conclusion: Forging the Future of Gladiators Battle

The latest enhancements to Gladiators Battle mark a significant leap toward providing a seamless and captivating experience for all players. With an enriched tutorial system, modular components, a thriving guild ecosystem, and optimized mini-games, the game is evolving into the ultimate gladiatorial RPG.

Whether you're a newcomer exploring the arena for the first time or a seasoned warrior dominating the battlefield, these updates ensure everyone can forge their own epic legacy.

๐Ÿ”— Join the Journey!

We are actively seeking feedback from players and developers alike. Dive into Gladiators Battle and share your thoughts with us.

๐ŸŒ Website: https://gladiatorsbattle.com
๐Ÿ›ก๏ธ Support Us on Kickstarter: https://www.kickstarter.com/projects/gladiatorsbattle/gladiators-battle-forge-your-legend-in-the-ultimate-arena
๐Ÿฆ Follow Us on X (formerly Twitter): https://x.com/GladiatorsBT
๐Ÿ’ผ Connect on LinkedIn: https://www.linkedin.com/in/pierre-romain-lopez
๐ŸŽฎ Join the Community on Discord: https://discord.gg/YBNF7KjGwx

Thank you for your unwavering support as we continue to develop Gladiators Battle. Your feedback, ideas, and enthusiasm are the driving forces behind our progress.

Let the adventure continueโ€”Ave, Gladiators! ๐Ÿบโœจ

If you have any questions or suggestions, please leave a comment below!

Top comments (0)