<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".
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"> | |
|---|---|---|
| Contenido | Cualquier HTML (texto, íconos, imágenes) | Solo texto plano (en value) |
| Uso en 2026 | Preferido | Legacy (pero válido) |
| Void element | No (tiene apertura y cierre) | Sí |
| Personalización CSS | Más flexible | Similar |
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
| Pseudoclase | Cuándo activa |
|---|---|
:hover | El cursor está sobre el botón |
:focus | El botón recibe foco (Tab o clic) |
:active | El instante en que se hace clic |
:disabled | El 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 essubmit. Es el bug silencioso más común en formularios complejos.- El texto del
<button>va entre las etiquetas, no envalue. El atributovalueen<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>.