elemento HTML vigente

<button>

Formularios

Elemento interactivo que crea un botón clicable. Dentro de un formulario, su type por defecto es submit — envía el formulario al clicarlo. A diferencia de <input type="submit">, puede contener cualquier contenido HTML (texto, íconos, imágenes).

<button> es el elemento que crea un botón interactivo en HTML. Su uso más común es dentro de formularios, donde actúa como desencadenante del envío, del reseteo, o de alguna acción JavaScript personalizada. Pero también puede usarse fuera de formularios, como cualquier control interactivo que requiera una acción al clicarlo: abrir un modal, mostrar/ocultar contenido, ejecutar una función.

Lo que distingue a <button> de <input type="submit"> o <input type="button"> es su modelo de contenido: <button> puede contener cualquier HTML entre sus etiquetas — texto formateado, iconos SVG, imágenes. Esto lo hace el elemento correcto para botones con íconos, botones con texto en negrita, o botones cuyo contenido es dinámico. Los <input> de tipo botón, al ser void elements, solo pueden mostrar texto plano en el atributo value.

El atributo type de <button> es crítico y tiene un default que sorprende a muchos principiantes: dentro de un <form>, un <button> sin type explícito se comporta como type="submit" y envía el formulario al clicarlo. Este comportamiento ha sido fuente de innumerables bugs: formularios que se envían al presionar un botón que no era el de submit, porque el botón olvidó declarar type="button".

type="submit" Enviar envía el formulario default en <form> type="reset" Limpiar borra todos los valores type="button" Acción JS no hace nada solo necesita addEventListener

Cómo funciona

<button> es un elemento de bloque inline interactivo. Cuando el usuario hace clic (o presiona Enter estando enfocado), el navegador ejecuta la acción correspondiente a su type. Si está dentro de un <form> y su type es submit, el navegador primero ejecuta la validación nativa de todos los controles del formulario; si pasa la validación, envía los datos al servidor. Si type es reset, restaura todos los controles del formulario a sus valores iniciales (los del atributo value o el estado vacío). Si type es button, no hace nada por defecto — la acción la define JavaScript.

Modelo de contenido

<button> acepta contenido en línea: texto, <strong>, <em>, <span>, <svg>, <img>. No puede contener elementos interactivos (<a>, <input>, otro <button>). Display por defecto: inline-block.

Sintaxis

<!-- Dentro de un form: submit envía, reset borra -->
<form action="/registro" method="post">
  <input type="text" name="nombre">
  <button type="submit">Registrarse</button>
  <button type="reset">Limpiar</button>
</form>

<!-- Fuera de un form o con type="button": no interactúa con el form -->
<button type="button" id="modal-btn">Abrir modal</button>

Atributos

type — comportamiento del botón

submit (default dentro de <form>) — envía el formulario que lo contiene. Si el formulario tiene validación nativa habilitada, la ejecuta primero.

reset — restaura todos los controles del formulario a sus valores iniciales. Poco usado en la práctica porque es frustrante para el usuario: puede borrar trabajo accidentalmente.

button — sin comportamiento nativo. Requiere JavaScript para hacer algo. Siempre declaralo explícitamente cuando el botón no debe enviar el formulario.

<!-- Botón que solo dispara JS: declarar type="button" es obligatorio dentro de un form -->
<button type="button" onclick="toggleMenu()">Menú</button>

Gotcha crítico: dentro de un <form>, un <button> sin type es submit. Si tenés un botón de “mostrar/ocultar contraseña” o “agregar campo dinámicamente” dentro de un form y no le ponés type="button", al clicarlo enviará el formulario. Es uno de los bugs más frecuentes en formularios HTML.

disabled — botón deshabilitado

Atributo booleano. El botón no puede clicarse, no recibe foco, y no dispara ningún evento.

<button type="submit" disabled>Enviando…</button>

CSS: :disabled para estilar el estado deshabilitado.

Uso común: deshabilitar el botón de submit después del primer clic para prevenir doble envío, hasta que el servidor responda.

form — asociar a un formulario externo

Permite que un <button> fuera del <form> actúe como si estuviera dentro. El valor es el id del formulario.

<form id="registro" action="/registro" method="post">
  <input type="text" name="nombre">
</form>

<!-- Este botón está fuera del form pero lo envía igual -->
<button type="submit" form="registro">Registrarse</button>

name y value — botón que envía datos

Un <button> puede tener name y value, en cuyo caso su par nombre=valor se incluye en el envío cuando ese botón fue el que disparó el submit. Útil cuando hay múltiples botones de submit con significados distintos.

<button type="submit" name="accion" value="guardar">Guardar borrador</button>
<button type="submit" name="accion" value="publicar">Publicar</button>

<button> vs <input type="submit">

<button type="submit"><input type="submit">
ContenidoCualquier HTML (texto, íconos, imágenes)Solo texto plano (en value)
Uso en 2026PreferidoLegacy (pero válido)
Void elementNo (tiene apertura y cierre)
Personalización CSSMás flexibleSimilar

En HTML moderno, <button> es siempre la opción preferida sobre <input type="submit"> porque permite contenido HTML. Los <input type="button"> y <input type="submit"> siguen siendo válidos y los vas a ver en código legado.

Estados e interacción

PseudoclaseCuándo activa
:hoverEl cursor está sobre el botón
:focusEl botón recibe foco (Tab o clic)
:activeEl instante en que se hace clic
:disabledEl botón tiene el atributo disabled
button {
  cursor: pointer;
}
button:focus-visible {
  outline: 2px solid #1d4ed8;
  outline-offset: 2px;
}
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

Accesibilidad

El texto entre las etiquetas del <button> es su nombre accesible. Si el botón contiene solo un ícono SVG sin texto, agregar aria-label para describir la acción:

<!-- Solo ícono: aria-label da el nombre accesible -->
<button type="button" aria-label="Cerrar diálogo">
  <svg>…</svg>
</button>

El rol implícito de <button> es button. Es navegable por teclado (Tab para llegar, Enter o Space para activar). Nunca uses <div> o <span> como botones con JS — perdés el rol semántico, la navegación por teclado y el anuncio de estado del lector de pantalla. Si necesitás un elemento clickable que no sea un enlace ni un botón de formulario, <button type="button"> es siempre la respuesta correcta.

Notas, gotchas e interacción

  • type="button" es obligatorio dentro de un form cuando el botón no debe enviar. Sin él, el default es submit. Es el bug silencioso más común en formularios complejos.
  • El texto del <button> va entre las etiquetas, no en value. El atributo value en <button> tiene un propósito distinto (el dato que envía cuando ese botón dispara el submit). No lo confundas con el texto visible.
  • <button> puede envolver bloques. Puede contener <span>, <svg>, <img> — pero no elementos interactivos como <a> o <input>.
  • No usar <a href="#"> como botón. Un <a> tiene semántica de navegación; un <button> tiene semántica de acción. Son roles distintos en el árbol de accesibilidad. Si la acción no navega a otra URL, usá <button>.

Vigente / legacy

<button> está completamente vigente. El patrón <input type="submit"> sigue siendo válido pero es heredado — se prefiere <button> por su flexibilidad de contenido. No hay atributos legacy relevantes en <button>.