albert.walickihire me
← all solutions
html

button vs input type=button: which one to use?

Why button type=button is the better choice over input type=button: HTML content, pseudo-elements, and the default submit type inside forms.

Use <button type="button">. It does everything <input type="button"> does, and it can hold more than plain text, so an icon next to the label is no problem.

<button type="button" class="button">
  <svg class="icon" aria-hidden="true">
    <use href="#icon-cart"></use>
  </svg>
  Add to cart
</button>

<!-- The same button as an input: text only -->
<input type="button" class="button" value="Add to cart">

What button can do that input can't

  • Content. <button> can contain HTML: icons, a <span> for a badge, visually hidden text. <input> is a void element with no closing tag, and its label is the value attribute, which is plain text only.
  • Pseudo-elements. ::before and ::after work on <button>, which is handy for spinners, arrows or decorative shapes. Don't count on them on <input>.
  • A value separate from the label. A submit <button> can send a name and value that differ from the visible text. With <input type="submit">, the value is the label, so translating the text changes what the server receives.
<button type="submit" name="action" value="draft">Save as draft</button>
<button type="submit" name="action" value="publish">Publish</button>

The gotcha: a button in a form submits it

A <button> without a type inside a <form> is a submit button. That's why a "Show password" button suddenly submits the form. Always write the type:

<form>
  <input type="password" name="password">
  <button type="button" class="toggle-password">Show</button>
  <button type="submit">Log in</button>
</form>

More on that in how to prevent a button from submitting a form.

<input type="button"> doesn't have this problem: it does nothing by default, anywhere, until you add a click listener. <input type="submit"> and <input type="reset"> still exist and work, but they have the same text-only limits, so I'd use <button type="submit"> there too.

What they have in common

Both are real buttons, which you don't get from a <div> with a click handler:

  • They're focusable with Tab.
  • Enter and Space activate them.
  • Screen readers announce them as buttons.
  • The disabled attribute takes them out of the tab order and blocks clicks.

Neither inherits the page font by default, so reset it when you style them:

.button {
  font: inherit;
  padding: 0.5rem 1rem;
  border: 0;
  border-radius: 6px;
  background: #1d4ed8;
  color: #fff;
  cursor: pointer;
}

If an old codebase uses <input type="button"> and it works, there's no need to rewrite it. For new code, reach for <button type="button">.

more solutions
work with me

Got something that needs building?

Frontend builds, full-stack features in Django, design-system work. Available for work.

See my workGet in touch