Sheath rule
best-practices-button-type
type attribute to prevent accidental form submission.
- Package
- Core
- Category
- Best Practices
- Default severity
- warning by default
- Auto-fix
- Auto-fix available
#Why
Without an explicit type, buttons default to type="submit" inside forms, which can cause accidental form submissions when users click buttons intended for other purposes (like opening modals or toggling content).
#Examples
#Bad
<!-- Missing type attribute -->
<button>Click me</button>
<!-- Inside a form, this will submit the form -->
<form>
<button>Open Modal</button>
</form>
<!-- Invalid type value -->
<button type="link">Go somewhere</button>
#Good
<!-- Explicit button type -->
<button type="button">Click me</button>
<!-- Submit button -->
<button type="submit">Submit Form</button>
<!-- Reset button -->
<button type="reset">Clear Form</button>
#Valid Type Values
Set type according to the action the button should perform.
| Value | Behavior |
|---|---|
button |
Does nothing by default - requires JavaScript |
submit |
Submits the containing form |
reset |
Resets the form to default values |
#Auto-fix
The fixer adds the type the button already has implicitly. A button inside a
<form> (or associated with one through the form attribute) is a submit
button, so it gets type="submit"; any other button gets type="button":
<!-- Before -->
<button>Click me</button>
<form method="post"><button>Save</button></form>
<!-- After -->
<button type="button">Click me</button>
<form method="post"><button type="submit">Save</button></form>
One case is marked dangerous rather than safe: a button with no <form>
ancestor in a file that is a fragment (no <html>/<body> in sight). A
partial's submit button looks exactly like that because the form lives in the
template that includes it. Adding type="button" would
silently stop the form from submitting. That fix only runs with
--dangerous. In a full page, a button outside every form provably submits
nothing, so the type="button" fix stays safe there.
#References
- HTML Spec: Button Type - The type attribute specification
- MDN: Button Element - Documentation on button type behavior
#Notes
- Missing
typeis not reported when button attributes are generated dynamically, such as with{{ $attributes->merge(['type' => 'submit']) }}or@if
#Related Rules
- a11y-button-accessible-name - Buttons need accessible names