使用动画构建高级多步骤表单

在本教程中,我们将逐步介绍如何使用 HTML、CSS 和 JavaScript 创建具有流畅动画和客户端验证的高级交互式多步骤表单。此表单提供了增强的用户体验,看起来就像是 2025 年的东西!

现场演示:https://codepen.io/HanGPIIIErr/pen/ZYzbrqW

目录

  • 介绍
  • 先决条件
  • 项目结构
  • HTML 标记
  • 使用 CSS 进行样式设置
  • 使用 JavaScript 添加交互性
  • 结论
  • 1.引言

    多步骤表单是将冗长的表单分解为可管理的部分来增强用户体验的绝佳方法。在本教程中,我们将创建一个包含以下内容的五步表单:

  • 个人信息
  • 偏好设置
  • 图片上传
  • 评论
  • 摘要及提交
  • 我们将在步骤之间添加流畅的动画并验证用户输入以确保数据完整性。

    先决条件

    对 HTML、CSS 和 JavaScript 有基本了解

    熟悉 JavaScript 中的表单元素和事件处理

    项目结构

    我们有三个主要文件:

    index.html — HTML 结构

    style.css — 表单的样式

    script.js — 处理表单交互的 JavaScript

    让我们首先设置 HTML 文件。

    
    
    
        
        Premium Multi-Step Form
        
        
    
    
        
    Step 1 of 5

    Personal Information

    Step 2 of 5

    Preferences

    Step 3 of 5

    Upload an Image

    Step 4 of 5

    Comments

    Step 5 of 5

    Summary

    解释

  • 表单步骤:每个步骤都包裹在一个带有 form-step 类的 div 中。
  • 活动类:第一步是让类处于活动状态以最初显示它。
  • 导航按钮:每个步骤(第一步和最后一步除外)都有“上一步”和“下一步”按钮。
  • 摘要部分:最后一步显示输入信息的摘要。
  • 使用 CSS 进行样式设置

    现在,让我们对表单进行样式设计,使其具有高档的感觉。

    /* 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);
        }
    }

    解释

  • 背景渐变:平滑的渐变带来现代感。
  • 形式样式:我们使用背景过滤器来实现玻璃态效果。
  • 过渡和动画:平滑的过渡和关键帧动画增强了交互性。
  • 按钮效果:悬停效果,带有轻微的移动和阴影以增加深度。
  • 使用 JavaScript 添加交互性
  • 让我们的表单具有功能性。

    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 = `
                

    Name: ${name}

    Email: ${email}

    Preferences: ${prefs}

    Comments: ${comments}

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

    解释

  • 事件监听器:使用“下一步”和“上一步”按钮在步骤之间导航。
  • 验证:validateStep() 确保填写必填字段。
  • 摘要显示:displaySummary() 编译输入的数据供用户审查。