Skip to content

button 按钮元素

<button> 元素用于创建可点击的按钮,它比 <input type="button"> 更灵活、更强大。<button> 元素可以包含任意 HTML 内容(文本、图标、图像),而 <input> 按钮只能显示纯文本。理解 <button><input type="button/submit/reset"> 的区别是构建高质量表单的基础。

前置知识

阅读本节前,建议先了解:textarea 多行文本

基础概念

什么是 button 元素

<button> 创建一个可点击的按钮,具有三种类型:

类型说明默认行为
type="submit"提交表单默认值,将所在表单的数据提交
type="reset"重置表单将表单中的所有控件恢复为初始值
type="button"普通按钮无默认行为,需要 JavaScript 处理

与 input 按钮的对比

特性<button><input type="button/submit">
内容可包含任意 HTML仅纯文本
图标原生支持不支持
无障碍内置文本标签仅 value 文本
样式控制灵活有限
嵌套元素可以不可以
value 属性可选(不用于显示)必需(用于显示)

重要提示:如果 <button> 在表单内且未指定 type 属性,默认行为是 提交表单。这是一个常见的 bug 来源。

语法

提交按钮

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>button 提交按钮</title>
</head>
<body>
    <h2>登录表单</h2>
    <form action="/login" method="post">
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username">

        <label for="password">密码:</label>
        <input type="password" id="password" name="password">

        <!-- 提交按钮 -->
        <button type="submit">登录</button>
    </form>
</body>
</html>

重置按钮

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>button 重置按钮</title>
</head>
<body>
    <h2>重置表单</h2>
    <form>
        <label for="name">姓名:</label>
        <input type="text" id="name" name="name" value="张三">

        <label for="email">邮箱:</label>
        <input type="email" id="email" name="email" value="zhangsan@example.com">

        <textarea name="note" rows="2">这是备注内容</textarea>

        <!-- 重置按钮:恢复所有字段为初始值 -->
        <button type="reset">重置表单</button>
    </form>
</body>
</html>

普通按钮

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>button 普通按钮</title>
</head>
<body>
    <h2>普通按钮</h2>
    <form>
        <input type="number" id="counter" name="counter" value="0" readonly>
        <button type="button" onclick="
            const input = document.getElementById('counter');
            input.value = parseInt(input.value) + 1;
        ">+1 计数</button>
    </form>
</body>
</html>

详细说明

按钮中的富内容

<button> 最大的优势是可以包含任意 HTML 内容:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>button 富内容</title>
</head>
<body>
    <h2>丰富的按钮内容</h2>
    <form>
        <!-- 图标 + 文本 -->
        <button type="submit">
            &#128640; 发送消息
        </button>

        <!-- HTML 格式化 -->
        <button type="submit">
            <strong>确认</strong><br>
            <small>点击提交表单</small>
        </button>

        <!-- 图像按钮 -->
        <button type="submit" style="border: none; background: none; cursor: pointer;">
            <img src="https://picsum.photos/80/30?text=Submit" alt="提交">
        </button>
    </form>
</body>
</html>

button 的 name 和 value

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>button name value</title>
</head>
<body>
    <h2>多按钮表单</h2>
    <form action="/action" method="get">
        <label for="query">搜索:</label>
        <input type="search" id="query" name="query">

        <!-- 不同按钮提交不同的 action 值 -->
        <button type="submit" name="action" value="search">搜索</button>
        <button type="submit" name="action" value="save">保存</button>
        <button type="submit" name="action" value="delete">删除</button>
    </form>

    <p>
        点击"搜索"提交:<code>query=xxx&action=search</code><br>
        点击"保存"提交:<code>query=xxx&action=save</code><br>
        点击"删除"提交:<code>query=xxx&action=delete</code>
    </p>
</body>
</html>

disabled 禁用按钮

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>button disabled</title>
</head>
<body>
    <h2>禁用按钮</h2>
    <form>
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username">

        <!-- 禁用的提交按钮 -->
        <button type="submit" disabled>请先填写用户名</button>
    </form>

    <script>
        // 用户输入内容后启用按钮
        const input = document.getElementById('username');
        const btn = document.querySelector('button[type="submit"]');

        input.addEventListener('input', function () {
            btn.disabled = this.value.trim() === '';
        });
    </script>
</body>
</html>

button 的 CSS 样式

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>button CSS 样式</title>
    <style>
        body { font-family: sans-serif; max-width: 600px; margin: 40px auto; }
        /* 重置默认样式 */
        button {
            padding: 10px 24px;
            border: none;
            border-radius: 6px;
            font-size: 16px;
            cursor: pointer;
            transition: all 0.2s ease;
            margin: 4px;
        }

        /* 主要按钮 */
        .btn-primary {
            background: #4a90d9;
            color: #fff;
        }
        .btn-primary:hover { background: #357abd; }
        .btn-primary:active { transform: scale(0.97); }

        /* 次要按钮 */
        .btn-secondary {
            background: #6c757d;
            color: #fff;
        }
        .btn-secondary:hover { background: #5a6268; }

        /* 危险按钮 */
        .btn-danger {
            background: #dc3545;
            color: #fff;
        }
        .btn-danger:hover { background: #c82333; }

        /* 轮廓按钮 */
        .btn-outline {
            background: transparent;
            border: 2px solid #4a90d9;
            color: #4a90d9;
        }
        .btn-outline:hover {
            background: #4a90d9;
            color: #fff;
        }

        /* 禁用状态 */
        button:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }
    </style>
</head>
<body>
    <h2>按钮样式</h2>
    <form>
        <button class="btn-primary" type="submit">主要按钮</button>
        <button class="btn-secondary" type="button">次要按钮</button>
        <button class="btn-danger" type="button">危险按钮</button>
        <button class="btn-outline" type="reset">轮廓按钮</button>
        <button type="button" disabled>禁用按钮</button>
    </form>
</body>
</html>

button 的 form 属性

<button> 可以通过 form 属性关联到表单外的表单:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>button form 属性</title>
</head>
<body>
    <h2>表单外部按钮</h2>
    <form id="my-form" action="/submit" method="post">
        <label for="data">输入数据:</label>
        <input type="text" id="data" name="data">
    </form>

    <!-- 此按钮在表单外部,但仍能提交 #my-form -->
    <button type="submit" form="my-form">提交</button>
    <button type="reset" form="my-form">重置</button>

    <p>按钮通过 <code>form</code> 属性关联到 ID 为 my-form 的表单。</p>
</body>
</html>

实战示例

确认对话框

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>按钮交互</title>
    <style>
        body { font-family: sans-serif; max-width: 500px; margin: 40px auto; }
        .dialog {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: #fff;
            padding: 24px;
            border-radius: 12px;
            box-shadow: 0 8px 32px rgba(0,0,0,0.2);
            z-index: 1000;
            text-align: center;
        }
        .dialog h3 { margin-top: 0; }
        .dialog-actions { margin-top: 16px; display: flex; gap: 12px; justify-content: center; }
        .dialog-actions button {
            padding: 8px 24px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 14px;
        }
        .btn-cancel { background: #eee; }
        .btn-confirm { background: #dc3545; color: #fff; }
        .overlay {
            display: none;
            position: fixed;
            inset: 0;
            background: rgba(0,0,0,0.3);
            z-index: 999;
        }
    </style>
</head>
<body>
    <h2>删除操作</h2>
    <button type="button" id="delete-btn" style="padding: 10px 24px; background: #dc3545; color: #fff; border: none; border-radius: 6px; cursor: pointer;">
        删除数据
    </button>

    <div class="overlay" id="overlay"></div>
    <div class="dialog" id="dialog">
        <h3>确认删除?</h3>
        <p>此操作不可撤销,确定要继续吗?</p>
        <div class="dialog-actions">
            <button type="button" class="btn-cancel" id="cancel-btn">取消</button>
            <button type="button" class="btn-confirm" id="confirm-btn">确认删除</button>
        </div>
    </div>

    <script>
        const deleteBtn = document.getElementById('delete-btn');
        const dialog = document.getElementById('dialog');
        const overlay = document.getElementById('overlay');
        const cancelBtn = document.getElementById('cancel-btn');
        const confirmBtn = document.getElementById('confirm-btn');

        function showDialog() {
            dialog.style.display = 'block';
            overlay.style.display = 'block';
        }
        function hideDialog() {
            dialog.style.display = 'none';
            overlay.style.display = 'none';
        }

        deleteBtn.addEventListener('click', showDialog);
        cancelBtn.addEventListener('click', hideDialog);
        overlay.addEventListener('click', hideDialog);
        confirmBtn.addEventListener('click', () => {
            hideDialog();
            deleteBtn.textContent = '已删除';
            deleteBtn.disabled = true;
            deleteBtn.style.background = '#999';
        });
    </script>
</body>
</html>

注意事项

表单内的 button 默认行为

<button> 在表单内的默认 typesubmit。如果只想执行 JavaScript 而不提交表单,必须显式设置 type="button"

html
<!-- 错误:点击会提交表单 -->
<button onclick="doSomething()">操作</button>

<!-- 正确:不会提交表单 -->
<button type="button" onclick="doSomething()">操作</button>

button 的 value 与显示文本

<button>value 属性是提交值,标签内容是显示文本,两者独立:

html
<!-- 提交值为 "save",显示为 "保存" -->
<button type="submit" name="action" value="save">保存</button>

button 中包含图像的双重提交

在某些旧浏览器中,点击 <button> 内的图像可能不会触发提交事件。使用 pointer-events: none 可以避免此问题。

防止重复提交

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>防止重复提交</title>
</head>
<body>
    <h2>防止重复提交</h2>
    <form id="submit-form" action="/submit" method="post">
        <input type="text" name="data" placeholder="输入数据">
        <button type="submit" id="submit-btn">提交</button>
    </form>

    <script>
        document.getElementById('submit-form').addEventListener('submit', function () {
            const btn = document.getElementById('submit-btn');
            btn.disabled = true;
            btn.textContent = '提交中...';

            // 模拟异步提交
            setTimeout(() => {
                btn.disabled = false;
                btn.textContent = '提交';
            }, 3000);
        });
    </script>
</body>
</html>

最佳实践

  1. 始终指定 type:明确声明按钮类型,避免隐式 submit 导致意外行为
  2. 优先使用 button:用 <button> 替代 <input type="button/submit/reset">,获得更好的灵活性
  3. 提供 disabled 状态:在条件不满足时禁用提交按钮
  4. 使用语义化名称:按钮文本应清晰描述操作(如"保存"而非"确定")
  5. 防止重复提交:表单提交后可暂时禁用按钮
  6. CSS 统一样式:使用一致的按钮样式系统

下一节

继续学习:output 输出元素

参考链接