Menu

Botones en HTML: tipos, submit, deshabilitados y estilos

Cómo crear un botón en HTML con el elemento <button>: los tres tipos (submit, button, reset), enviar un valor con el formulario, botones deshabilitados, iconos y estilos CSS que conservan el anillo de foco.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Cómo hacer un botón en HTML

Un botón es el elemento <button>. El contenido entre las etiquetas es lo que ve el usuario, y type="button" indica que ejecuta tu script en lugar de enviar un formulario. Púlsalo en la vista previa:

Eso es todo lo que necesita un botón que funcione: una etiqueta, un type y algo que escuche el click. El navegador hace que reciba el foco con el teclado y lo activa con Enter o Espacio, así que quienes usan el teclado lo tienen sin hacer nada más. Un <div> con un manejador de clic no tiene nada de eso.

También verás onclick="..." escrito directamente en la etiqueta. Funciona, pero addEventListener mantiene el script fuera del marcado y permite que varios listeners compartan un botón.

Los tres tipos de botón

El atributo type decide qué hace un botón al pulsarlo.

typeQué haceÚsalo para
submitEnvía el formulario al que pertenece. Es el valor por defecto.La acción principal de un formulario
buttonNada por sí solo; tu JavaScript decideInterruptores, diálogos, contadores, cualquier cosa con script
resetDevuelve todos los campos del formulario a su valor inicialCasi nunca; los usuarios lo pulsan por error

Escribe algo y prueba cada botón. La vista previa no sale de la página cuando se envía el formulario; muestra los datos que el formulario habría enviado.

Reset restaura el valor escrito en el HTML (Ada), no un campo vacío. Y si borras type="button" de Uppercase, se convierte en un botón de envío: pasa el nombre a mayúsculas y luego envía el formulario.

Botón submit en HTML: enviar un name y un value

Un botón de envío puede llevar su propio name y value. Se envían con el formulario solo cuando ese botón es el que lo envió, así que dos botones pueden compartir un formulario y decirle al servidor qué acción se eligió:

Pulsa Publish y el formulario envía title=My first post y action=publish. Vacía el título y pulsa cualquiera de los dos: required detiene el envío y el navegador muestra su propio mensaje. Pulsar Enter dentro del campo de texto también envía, y el navegador lo trata como una pulsación del primer botón de envío, así que manda action=draft.

Los botones de envío también aceptan atributos que sobrescriben el formulario solo para ese botón: formaction (otra URL), formmethod, formtarget y formnovalidate, que se salta la validación. formnovalidate es la opción habitual para un botón de "Guardar borrador" que debe funcionar aunque los campos obligatorios sigan vacíos.

Un botón colocado fuera de su formulario puede enviarlo igualmente con el atributo form, que recibe el id del formulario: <button type="submit" form="signup">Sign up</button>.

Botones deshabilitados

El atributo disabled desactiva un botón. Un botón deshabilitado ignora los clics, Tab lo salta y no se envía con el formulario. Los navegadores además lo muestran en gris. Un patrón habitual es mantener deshabilitado el botón de envío hasta que se cumpla una condición:

En JavaScript, button.disabled es una propiedad booleana: ponla a true o false. En HTML cuenta la presencia del atributo, así que disabled="false" sigue deshabilitando el botón.

Un botón deshabilitado no explica por qué lo está, y quienes navegan con Tab usando el teclado o un lector de pantalla nunca llegan a él. Cuando el motivo no es evidente, dilo con texto junto al botón, o deja el botón habilitado y muestra un mensaje de error al pulsarlo.

Dar estilo a un botón con CSS

Los navegadores dibujan los botones con su propia fuente, borde y fondo. Definir unas pocas propiedades reemplaza todo eso. Mantén un estilo de foco visible: es como quienes usan el teclado ven dónde están.

Para qué sirve cada regla:

  • font: inherit hace que el botón use la fuente de la página. Sin ella, los botones usan la fuente de formulario del navegador, más pequeña (13.33px en Chrome y Firefox).
  • cursor: pointer muestra el cursor de mano. Los botones muestran la flecha normal por defecto.
  • :hover, :active y :focus-visible dan estilo a los estados de puntero, pulsación y teclado. :focus-visible muestra el anillo con el foco del teclado pero no después de un clic del ratón, así que no tienes que quitar outline para evitarlo.
  • :disabled selecciona los botones con el atributo disabled.

Pulsa Tab en la vista previa para ver cómo el anillo de foco ámbar se mueve entre los dos primeros botones. El deshabilitado se salta. (En Mac, Safari y Firefox solo llegan a los botones con Tab cuando la navegación por teclado está activada en los ajustes del sistema; en Safari, Opción+Tab funciona sin ella.) Para la lista completa de estados, consulta hover en CSS.

Botones con iconos

Como <button> puede contener HTML, un icono va dentro junto al texto. Un botón solo con icono no tiene texto que anunciar a los lectores de pantalla, así que dale un aria-label:

aria-hidden="true" en el SVG lo deja fuera del árbol de accesibilidad, así que el primer botón se anuncia como "Add item, botón" y el segundo como "Delete, botón".

button vs input type="submit"

<input type="submit"> es la forma antigua de escribir un botón de envío. Los dos envían el formulario igual; la diferencia está en lo que pueden contener.

<input type="submit" value="Send">   <!-- label comes from value, text only -->
<button type="submit">Send</button>  <!-- label is the content, HTML allowed -->
<button><input type="submit">
EtiquetaEl contenido entre las etiquetasEl atributo value
Puede contener iconos o marcadoSíNo
Etiqueta de cierreObligatoriaNinguna (elemento vacío)
Tipo por defectosubmitSiempre envía

Usa <button>. El único motivo para mantener <input type="submit"> es un CSS o JavaScript existente que lo seleccione. También existen <input type="button"> e <input type="reset">, la misma idea para los otros dos tipos.

¿Botón o enlace?

Un botón hace algo en la página actual: envía, abre, alterna, borra. Un enlace va a otra URL. Si al pulsarlo cambia la barra de direcciones, debe ser un <a href>, con estilo de botón si el diseño lo pide. Ese patrón, y por qué un botón dentro de un enlace no es válido, se explica en botón con enlace en HTML.

Accesibilidad

  • Usa un <button> real. Recibe el foco, funciona con Enter y Espacio y se anuncia como botón. Reconstruir eso sobre un <div> exige role, tabindex y manejadores de teclas, y normalmente sigue quedando incompleto.
  • Todo botón necesita un nombre: su texto, o aria-label cuando solo tiene un icono.
  • Mantén un estilo de foco visible. outline: none sin sustituto deja perdidos a quienes usan el teclado.
  • Haz el área lo bastante grande para acertar. WCAG 2.2 pide al menos 24 por 24 píxeles CSS; un padding como el del ejemplo con estilos da unos 40 píxeles de alto.
  • Para un interruptor, añade aria-pressed="true" o "false" y actualízalo cuando cambie el estado.

Errores comunes

  • Un botón en un formulario sin type. Envía el formulario. Escribe type="button" en todo botón que no deba enviar.
  • Envolver un botón en un enlace, <a href="/x"><button>Go</button></a>. Es HTML no válido y se comporta distinto según el navegador. Usa un solo elemento: un enlace con estilo de botón.
  • Usar <div onclick> como botón. No se puede alcanzar con el teclado.
  • Quitar el contorno de foco sin añadir un estilo :focus-visible.
  • Escribir disabled="false" y esperar un botón habilitado. Quita el atributo.
  • Olvidar font: inherit y preguntarse por qué los botones usan una fuente distinta del resto de la página.

Preguntas frecuentes

¿Cómo se hace un botón en HTML?

Escribe <button type="button">Haz clic</button>. El texto entre las etiquetas es la etiqueta visible. Añade un listener de click en JavaScript para que haga algo, o ponlo dentro de un <form> con type="submit" para enviar el formulario.

¿Cuál es el tipo por defecto de un botón HTML?

submit. Un <button> sin atributo type dentro de un formulario envía ese formulario al pulsarlo, y por eso un botón normal dentro de un formulario puede recargar la página. Escribe type="button" en cualquier botón que ejecute JavaScript.

¿Qué diferencia hay entre button e input type=submit?

Los dos envían un formulario. <button> puede contener HTML (un icono, texto en negrita) entre sus etiquetas, mientras que <input type="submit"> toma su etiqueta del atributo value y solo admite texto plano. La mayor parte del código moderno usa <button>.

¿Cómo deshabilito un botón en HTML?

Añade el atributo disabled: <button disabled>Guardar</button>. Un botón deshabilitado no se puede pulsar ni recibe el foco, y su nombre y valor no se envían con el formulario. Quita el atributo (btn.disabled = false en JavaScript) para volver a habilitarlo.

¿Cómo hago que un botón HTML lleve a otra página?

Usa un enlace con estilo de botón: <a href="/pricing" class="btn">Ver precios</a>. Un <button> es para acciones en la página actual. Envolver un botón en <a> es HTML no válido.

¿Por qué mi botón recarga la página?

Está dentro de un <form> y no tiene type, así que es un botón de envío y el navegador envía el formulario y carga la respuesta. Añádele type="button", o llama a event.preventDefault() en un listener de submit si gestionas el formulario con JavaScript.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR