HTML buttons in forms: submit behavior, types, and UX
Buttons look simple, but they control the most important moment in a form: submission. A confusing button can cause accidental submissions, duplicate submissions, or no submission at all.
The key is to be explicit. Use the correct button type, write action-specific labels, provide loading feedback for JavaScript submissions, and keep the form usable without JavaScript when possible.
Basic submit button
<form action="https://api.formsfort.com/submit" method="POST"> <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
<label for="email">Email</label> <input type="email" id="email" name="email" required />
<button type="submit">Subscribe</button></form>Always include type="submit" on submit buttons. It documents the behavior and avoids surprises when buttons are moved around later.
Button types
| Type | Behavior |
|---|---|
submit | Submits the form |
button | Does nothing by default, useful for JavaScript actions |
reset | Resets all fields to their initial values |
Inside a form, <button> defaults to submit. That means this button submits the form even though it may look like a secondary action:
<button>Preview</button>Make non-submit actions explicit:
<button type="button">Preview</button>Use clear action labels
Button labels should describe the result.
| Weak label | Better label |
|---|---|
| Submit | Send message |
| Continue | Continue to payment |
| OK | Save preferences |
| Click here | Download quote |
For forms, the best labels usually start with a verb: send, save, create, request, subscribe, download, upload.
Multiple submit buttons
Forms can include more than one submit action. Give each button a name and value so the backend can see which one was clicked.
<form action="https://api.formsfort.com/submit" method="POST"> <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
<label for="email">Email</label> <input type="email" id="email" name="email" required />
<button type="submit" name="intent" value="save_draft">Save draft</button> <button type="submit" name="intent" value="send_request">Send request</button></form>If the visitor clicks “Send request”, the backend receives intent=send_request.
Prevent duplicate AJAX submissions
For JavaScript-enhanced forms, disable the submit button while the request is in progress and expose status text with aria-live.
<form id="contactForm" action="https://api.formsfort.com/submit" method="POST"> <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" /> <input type="email" name="email" required /> <textarea name="message" required></textarea> <button type="submit" id="submitButton">Send message</button> <p id="formStatus" aria-live="polite"></p></form>
<script> const form = document.getElementById("contactForm"); const button = document.getElementById("submitButton"); const status = document.getElementById("formStatus");
form.addEventListener("submit", async (event) => { event.preventDefault(); button.disabled = true; status.textContent = "Sending...";
try { const response = await fetch(form.action, { method: "POST", body: new FormData(form), });
status.textContent = response.ok ? "Message sent." : "The message could not be sent."; } finally { button.disabled = false; } });</script>Do this only when JavaScript owns the submission. A regular HTML form does not need this code.
Style disabled buttons accessibly
Disabled buttons should look disabled, but the text still needs enough contrast to be readable.
button { border: 0; border-radius: 8px; padding: 12px 16px; background: #059669; color: white; font-weight: 700;}
button:disabled { cursor: not-allowed; opacity: 0.65;}Avoid hiding the button or changing its label to only a spinner. If you use an icon or spinner, keep text available for screen readers.
Complete backend-ready form
<form action="https://api.formsfort.com/submit" method="POST"> <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" /> <input type="hidden" name="subject" value="New demo request" />
<label for="email">Work email</label> <input type="email" id="email" name="email" autocomplete="email" required />
<label for="message">What should we help with?</label> <textarea id="message" name="message" rows="5" required></textarea>
<input type="checkbox" name="botcheck" style="display:none" />
<button type="submit">Request demo</button></form>This form works on static hosting, has an explicit submit action, and sends clear field names to the backend.
Related guides
Use this with the HTML input fields guide, HTML textarea guide, and HTML form validation guide.
Frequently asked questions
What is the default type for a button in a form?
Inside a form, a button defaults to type='submit'. Set type explicitly to avoid accidental submissions.
When should I use input type='submit' instead of button?
Use button for most modern forms because it can contain richer content. input type='submit' is still valid for simple submit controls.
Can a form have multiple submit buttons?
Yes. Each submit button can have its own name and value, so the backend can tell which action was chosen.
Should I disable the submit button after click?
You can disable it while an AJAX request is in progress, but keep an accessible status message so users know what is happening.
Get started free
Ready to add forms to your static site?
No backend required. Point your HTML form at FormsFort and start receiving submissions in minutes.