• 现代化设计:采用卡片式布局,有阴影和圆角,视觉效果清爽。
  • 完全响应式:在桌面、平板和手机上都有出色的显示效果。
  • 表单验证:使用 HTML5 原生验证功能,确保用户输入有效信息。
  • 交互反馈:包含加载状态、成功/错误提示,提升用户体验。
  • 可扩展性:结构清晰,易于添加“记住我”、“忘记密码”或第三方登录(如微信、QQ)等功能。
  • 无障碍性:使用了 labelfor 属性,方便屏幕阅读器操作。

最终效果预览

  • 桌面端:

    html5登陆页面模板自适应
    (图片来源网络,侵删)
  • 移动端:


完整代码

您可以直接复制以下所有代码,保存为一个 .html 文件(login.html),然后在浏览器中打开即可看到效果。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">登录 - 您的网站名称</title>
    <!-- 引入字体图标库 (Font Awesome) -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        /* --- 全局样式和变量 --- */
        :root {
            --primary-color: #4a90e2;
            --primary-hover-color: #357abd;
            --error-color: #e74c3c;
            --success-color: #2ecc71;
            --bg-color: #f4f7f6;
            --card-bg-color: #ffffff;
            --text-color: #333333;
            --border-color: #dddddd;
        }
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--bg-color);
            color: var(--text-color);
            line-height: 1.6;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        /* --- 登录容器 --- */
        .login-container {
            width: 100%;
            max-width: 420px;
            padding: 20px;
        }
        .login-card {
            background-color: var(--card-bg-color);
            padding: 40px;
            border-radius: 10px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
            text-align: center;
        }
        .login-card h1 {
            margin-bottom: 10px;
            font-size: 28px;
            color: var(--primary-color);
        }
        .login-card p {
            margin-bottom: 30px;
            color: #777;
            font-size: 16px;
        }
        /* --- 表单元素 --- */
        .form-group {
            margin-bottom: 20px;
            text-align: left;
        }
        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 500;
            font-size: 14px;
        }
        .input-wrapper {
            position: relative;
        }
        .input-wrapper i {
            position: absolute;
            left: 15px;
            top: 50%;
            transform: translateY(-50%);
            color: #aaa;
        }
        .form-control {
            width: 100%;
            padding: 12px 15px 12px 45px; /* 为图标留出空间 */
            border: 1px solid var(--border-color);
            border-radius: 5px;
            font-size: 16px;
            transition: border-color 0.3s, box-shadow 0.3s;
        }
        .form-control:focus {
            outline: none;
            border-color: var(--primary-color);
            box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
        }
        .form-control:invalid {
            border-color: var(--error-color);
        }
        /* --- 按钮样式 --- */
        .btn {
            display: inline-block;
            width: 100%;
            padding: 12px;
            background-color: var(--primary-color);
            color: #ffffff;
            border: none;
            border-radius: 5px;
            font-size: 16px;
            font-weight: bold;
            cursor: pointer;
            transition: background-color 0.3s, transform 0.2s;
        }
        .btn:hover {
            background-color: var(--primary-hover-color);
        }
        .btn:active {
            transform: scale(0.98);
        }
        .btn:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
            transform: none;
        }
        /* --- 提示信息 --- */
        .alert {
            padding: 12px 15px;
            margin-bottom: 20px;
            border-radius: 5px;
            font-size: 14px;
            display: none; /* 默认隐藏 */
        }
        .alert-success {
            background-color: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }
        .alert-error {
            background-color: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }
        /* --- 加载动画 --- */
        .spinner {
            display: none;
            width: 20px;
            height: 20px;
            margin: 0 auto;
            border: 3px solid rgba(255, 255, 255, 0.3);
            border-radius: 50%;
            border-top-color: #fff;
            animation: spin 1s ease-in-out infinite;
        }
        @keyframes spin {
            to { transform: rotate(360deg); }
        }
        .btn.loading .btn-text {
            visibility: hidden;
        }
        .btn.loading .spinner {
            display: block;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }
        /* --- 额外链接 --- */
        .form-footer {
            margin-top: 25px;
            font-size: 14px;
            color: #777;
        }
        .form-footer a {
            color: var(--primary-color);
            text-decoration: none;
            font-weight: 500;
        }
        .form-footer a:hover {
            text-decoration: underline;
        }
        /* --- 响应式设计 --- */
        @media (max-width: 480px) {
            .login-container {
                padding: 10px;
            }
            .login-card {
                padding: 30px 20px;
            }
            .login-card h1 {
                font-size: 24px;
            }
        }
    </style>
</head>
<body>
    <div class="login-container">
        <div class="login-card">
            <h1>欢迎回来</h1>
            <p>请登录您的账户以继续</p>
            <!-- 提示信息区域 -->
            <div id="alert-box" class="alert"></div>
            <form id="login-form" novalidate>
                <div class="form-group">
                    <label for="username">用户名 / 邮箱</label>
                    <div class="input-wrapper">
                        <i class="fas fa-user"></i>
                        <input 
                            type="text" 
                            id="username" 
                            class="form-control" 
                            placeholder="请输入用户名或邮箱"
                            required
                            autofocus
                        >
                    </div>
                </div>
                <div class="form-group">
                    <label for="password">密码</label>
                    <div class="input-wrapper">
                        <i class="fas fa-lock"></i>
                        <input 
                            type="password" 
                            id="password" 
                            class="form-control" 
                            placeholder="请输入您的密码"
                            required
                            minlength="6"
                        >
                    </div>
                </div>
                <button type="submit" id="login-btn" class="btn">
                    <span class="btn-text">登 录</span>
                    <div class="spinner"></div>
                </button>
            </form>
            <div class="form-footer">
                <p>还没有账户? <a href="#">立即注册</a></p>
                <p><a href="#">忘记密码?</a></p>
            </div>
        </div>
    </div>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const loginForm = document.getElementById('login-form');
            const loginBtn = document.getElementById('login-btn');
            const alertBox = document.getElementById('alert-box');
            // 表单提交处理
            loginForm.addEventListener('submit', function (event) {
                // 阻止表单默认提交行为
                event.preventDefault();
                // 获取表单数据
                const username = document.getElementById('username').value;
                const password = document.getElementById('password').value;
                // 清除之前的提示信息
                hideAlert();
                // --- 模拟登录验证 ---
                // 在实际项目中,这里会是一个 AJAX 请求到后端服务器
                if (username === 'admin' && password === '123456') {
                    // 模拟成功
                    showAlert('登录成功!正在跳转...', 'success');
                    // 模拟加载状态
                    setLoadingState(true);
                    setTimeout(() => {
                        // 跳转到首页或其他页面
                        // window.location.href = 'dashboard.html';
                        console.log('登录成功,准备跳转...');
                        setLoadingState(false);
                    }, 1500);
                } else {
                    // 模拟失败
                    showAlert('用户名或密码错误,请重试!', 'error');
                }
            });
            // 显示提示信息
            function showAlert(message, type) {
                alertBox.textContent = message;
                alertBox.className = `alert alert-${type}`;
                alertBox.style.display = 'block';
            }
            // 隐藏提示信息
            function hideAlert() {
                alertBox.style.display = 'none';
            }
            // 设置按钮加载状态
            function setLoadingState(isLoading) {
                if (isLoading) {
                    loginBtn.disabled = true;
                    loginBtn.classList.add('loading');
                } else {
                    loginBtn.disabled = false;
                    loginBtn.classList.remove('loading');
                }
            }
        });
    </script>
</body>
</html>

代码解析

HTML 结构 (<body> 部分)

  • 语义化标签:使用了 <main> (虽然这里用 <div class="login-container"> 更常见,因为 main 通常用于页面主要内容区,而登录页可能是一个覆盖层) 和 <form>
  • 表单元素
    • input[type="text"]input[type="password"]:用于用户输入。
    • required 属性:HTML5 原生验证,确保字段不为空。
    • autofocus:页面加载后自动聚焦到用户名输入框。
    • minlength="6":对密码长度进行基本限制。
    • labelfor 属性:与 inputid 关联,点击 label 时可以聚焦到对应的输入框,提升了可访问性。
  • 图标:使用 <i> 标签和 Font Awesome 类名(如 fas fa-user)来添加输入框前的图标。
  • 按钮<button type="submit"> 用于触发表单提交。
  • 提示区域<div id="alert-box"> 用于动态显示成功或错误信息。

CSS 样式 (<style> 部分)

  • CSS 变量:在 root 中定义了颜色变量,方便全局统一修改主题色。
  • Flexbox 布局body 使用 display: flexjustify-content: centeralign-items: center 轻松实现水平和垂直居中。
  • 响应式设计
    • 移动优先.login-containerwidth: 100%max-width: 420px 确保在小屏幕上宽度自适应,在大屏幕上有一个固定的最大宽度。
    • 媒体查询@media (max-width: 480px) 针对更小的屏幕(如手机)调整内边距和字体大小,优化显示效果。
  • 交互效果
    • focus 伪类:为输入框获得焦点时添加蓝色边框和光晕效果。
    • hoveractive 伪类:为按钮和链接添加悬停和点击时的视觉反馈。
    • 过渡效果 (transition):让颜色、阴影等变化更平滑。

JavaScript 交互 (<script> 部分)

  • DOM 加载完成:使用 DOMContentLoaded 事件确保 HTML 完全解析后再执行 JS 代码。
  • 表单提交监听addEventListener('submit', ...) 监听表单的提交事件。
  • event.preventDefault()非常重要,阻止表单默认的刷新页面的提交行为,从而让我们可以用 JS 控制流程。
  • 数据获取:通过 document.getElementById().value 获取用户输入的用户名和密码。
  • 模拟验证:这里用一个简单的 if 判断来模拟后端验证。在实际项目中,这里会替换为 fetchaxios 发送 AJAX 请求到服务器。
  • 动态提示showAlert()hideAlert() 函数通过修改 alertBoxclassNamestyle.display 来显示不同类型(成功/错误)的消息。
  • 加载状态setLoadingState() 函数通过修改按钮的 disabled 状态和添加 loading 类,来显示一个旋转的加载动画,防止用户重复点击,并给予用户操作反馈。

如何扩展和修改

  1. 修改主题色:只需修改 root 中的 --primary-color--primary-hover-color 变量。
  2. 添加“记住我”功能:在表单中添加一个 <input type="checkbox">,并在提交时获取其状态,通过 AJAX 发送给后端。
  3. 添加第三方登录:在 .form-footer 上方添加新的按钮组,
    <div class="social-login">
        <a href="#" class="btn btn-wechat"><i class="fab fa-weixin"></i> 微信登录</a>
    </div>
  4. 连接真实后端:将 JS 中的 if 判断逻辑替换为 fetch 请求:
    // 替换原有的 if-else 逻辑
    fetch('https://api.yourserver.com/login', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ username, password }),
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            showAlert('登录成功!', 'success');
            // ...
        } else {
            showAlert(data.message || '登录失败', 'error');
        }
    })
    .catch(error => {
        showAlert('网络错误,请稍后重试', 'error');
        console.error('Error:', error);
    });
html5登陆页面模板自适应
(图片来源网络,侵删)