La etiqueta <input> con números

Controles: Campos de entrada numéricos


Aunque con la etiqueta <input type="text"> podríamos permitir al usuario que inserte números, no tenemos ningún tipo de control de como los introduce. Por ejemplo, el usuario podría escribir el número con texto, o añadir carácteres que no son números, lo que complicaría su posterior revisión o manipulación de datos al no estar en el mismo formato.

Campos de contenido numérico

Para permitir al usuario introducir números, lo podemos hacer de dos formas, utilizando la etiqueta <input> con diferentes valores en el atributo type. Son las dos siguientes:

Tipo de información a obtener Etiqueta a utilizar Ejemplo
Número (expresado en cifras) <input type="number">
Número (expresado en rango) <input type="range">

Vamos a analizarlas detenidamente.

El atributo type="number"

La primera de ellas es <input type="number">, una etiqueta mediante la cuál el usuario puede indicar la cifra numérica que quiere enviar en el formulario. La diferencia principal respecto a los campos de texto es que:

  • Al escribir la cifra, nos aparecen flechitas de aumentar y disminuir la cantidad.
  • Sólo se permite escribir números y carácteres permitidos.
Carácteres Descripción
Dígitos 0-9 Para indicar las diferentes cifras.
Signo + Para indicar números positivos.
Signo - Para indicar números negativos.
Número e Para indicar números relacionados con el número e.
Signos . o , Para indicar la parte decimal.

Así pues, con estos datos, los siguientes ejemplos son válidos para el navegador:

<input type="number" value="5.0">
<input type="number" value="10">
<input type="number" value="-5">

En el primero de ellos tenemos un número decimal, en el segundo un número positivo y en el tercero un número negativo. Todos válidos. Observa que en el atributo value no puedes indicar e o + porque, a pesar de ser carácteres permitidos, el navegador los permite para computarlos y traducirlos a número, pero no los permite usar en value.

El atributo type="range"

Por otro lado, tenemos la etiqueta <input type="range">, que en lugar de mostrarnos un campo de texto donde podemos insertar los números directamente, podemos hacerlo mediante un «slider» o barra de desplazamiento que representa un número entre un rango numérico específico. Funciona exactamente igual que <input type="number">, sólo que se muestra mediante un slider.

<input type="range" value="5.0">
<input type="range" value="10">
<input type="range" value="-5">

Sin embargo, este método tiene dos inconvenientes:

  • Por defecto, no se muestra el valor elegido.
  • Por defecto, los valores mínimo y máximo son 0 y 100.

El primer inconveniente lo podríamos solucionar, de forma accesible, adaptando el <input> al siguiente fragmento de código. Observa que lo que hemos hecho es añadir un <output> para añadir el valor del <input>, y actualizarlo mediante Javascript con el evento onInput. Eso sí, recuerda que el campo <output> debería estar siempre después del elemento:

<input type="range" value="5.0" onInput="this.nextElementSibling.value = this.value">
<output>5.0</output>

El segundo inconveniente se puede solucionar con los atributos min y max que explicamos en el siguiente apartado.

Mínimos y máximos

En ambas etiquetas <input> numéricas se pueden indicar los atributos min y max para restringir el valor mínimo y máximo que puedes escribir en el campo de entrada de datos:

Atributo Significado del atributo
min Número mínimo permitido para considerarse correcto (pasar validación).
max Número máximo permitido para considerarse correcto (pasar validación).

Esto no significa que el usuario no pueda introducir un número menor que el indicado en el atributo min, por ejemplo, sino que si el usuario introduce ese número, los datos del campo no serán válidos, y si tenemos validaciones, no se podrá enviar el formulario hasta que se cumplan esas restricciones. Estos detalles lo veremos más adelante, en el apartado de Validaciones HTML5.

Observemos este fragmento de código:

<form method="post" action="/send/">
  Un valor numérico:
  <input type="number" value="25" min="10" max="50">

  Un valor numérico en rango:
  <input type="range" value="25" min="10" max="50"
         onInput="this.nextElementSibling.value = this.value">
  <output>25</output>
</form>

Las diferencias son las siguientes:

  • En el campo con type a number es posible introducir manualmente números no permitidos.
  • En el campo con type a range no es posible salirse del rango indicado.
  • Tanto en uno como en otro, no es posible enviar el formulario si no se cumplen las restricciones.

Saltos

Mediante el atributo step puedes marcar la cantidad numérica que se incrementará o decrementará al pulsar en las flechas de un campo type="number" o al mover el slider de un campo type="range". Si este atributo se omite, por defecto será 1, pero indicándolo expresamente, podemos cambiar su valor.

Atributo Significado del atributo
step Variación de incrementos o decrementos entre números para considerarse correcto (pasar validación).

De la misma forma que antes, siempre se puede establecer uno de estos valores, pero no cumpliría la restricción de step:

<form method="post" action="/send/">
  <input type="number" value="25" min="10" max="50" step="5">

  <input type="range" value="25" min="10" max="50" step="5"
         onInput="this.nextElementSibling.value = this.value">
  <output>25</output>
</form>

En este ejemplo, indicando min=10 y max=50, pongamos tres ejemplos:

  • Con step=5, los valores permitidos serían: 10, 15, 20, 25, 30, 35, 40, 45 y 50.
  • Con step=10, los valores permitidos serían: 10, 20, 30, 40 y 50.
  • Con step=15, los valores permitidos serían: 10, 25 y 40.

Ten en cuenta que también se podrían indicar valores decimales en el atributo step.

Personalizar apariencia

Los campos numéricos <input type="number"> se personalizan como cualquier otro elemento de texto (con algunos añadidos), sin embargo, los elementos <input type="range"> tienen mayor capacidad de personalización mediante CSS. Veamos sus características.

Contenido numérico

A continuación, veamos una lista de selectores que puedes utilizar para personalizar el diseño de los campos numéricos:

Selector Descripción
input[type="number"] Elemento de entrada de datos numéricos vía campo de texto.
::textfield-decoration-container Contenedor específico de la información numérica.
::inner-spin-button Contenedor del botón pulsable para cambiar números.

Observa que hay unos botones para cambiar el valor numérico cuando mueves el ratón sobre el campo de texto. Estos botones, en realidad son uno sólo, que suma o resta dependiendo de la región del botón en la que pulses. Veamos un ejemplo de personalización:

input[type="number"].custom {
  height: 40px;
  background: #333;
  border: 3px solid gold;
  border-radius: 8px;
  color: #fff;
  font-size: 1.1rem;

  &::-webkit-textfield-decoration-container {
    background: #000;
    padding: 0.5rem 1rem;
  }

  &::-webkit-inner-spin-button {
    appearance: none;
    width: 20px;
    height: 25px;
    background: linear-gradient(green 49%, transparent 49% 51%, red 51%);
    box-shadow: 0 0 5px 3px #000 inset;
    opacity: 1;
  }
}
<input type="number">
<input class="custom" type="number">

En los navegadores, observa que alrededor del campo numérico, al pulsar en él, aparece un borde negro adicional. Es el que podemos modificar mediante la propiedad outline o contorno. Aunque el primer reflejo es eliminarlo porque visualmente no coincide con el diseño, recuerda que se trata de una ayuda visual que es ideal en contextos de accesibilidad.

Slider numérico

Por otro lado, el campo <input type="range"> muestra por defecto un slider horizontal con un tope para marcar la posición. Los selectores especial para este tipo de elemento son los siguientes:

Selector Descripción
input[type="range"] Elemento de tipo slider para representar números.
::slider-runnable-track Contenedor de toda la banda del slider.
::slider-container Contenedor interno de la banda del slider.
::slider-thumb Contenedor del nodo de selección del slider.

Como mejor se entienden estos detalles es con un ejemplo, así que vamos a examinar un ejemplo aplicado donde modificar el estilo de un campo numérico de tipo slider.

input[type="range"].custom {
  appearance: none;
  margin: 1rem 0;

  &::-webkit-slider-runnable-track {
    background: none;
  }

  &::-webkit-slider-container {
    background: darkred;
    box-shadow: 0 0 4px #0006 inset;
    height: 8px;
  }

  &::-webkit-slider-thumb {
    appearance: none;
    width: 18px;
    height: 32px;
    box-shadow: 0 0 4px #0006;
    background: conic-gradient(#222, #888, #444, #222);
    border-radius: 16px;
  }
}
<input type="range">
<input class="custom" type="range">

Observa que en algunas partes debemos utilizar la propiedad appearance para eliminar la apariencia del sistema operativo y crear una personalidad y propia.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev