elemento HTML vigente

<input>

Formularios

Void element de formulario cuyo comportamiento y apariencia cambian completamente según el valor del atributo type: desde un campo de texto hasta un selector de color, fecha, archivo o un checkbox. Es el control de formulario más versátil del HTML.

<input> es el control de formulario más versátil del HTML y, por esa misma razón, el más complejo. A diferencia de casi todos los elementos HTML —que tienen un propósito fijo— <input> cambia completamente su comportamiento, su apariencia y las restricciones de validación que acepta según el valor de su atributo type. Un <input type="text"> es un campo de texto libre; un <input type="checkbox"> es una casilla de verificación; un <input type="color"> abre un selector de color. Son visualmente distintos, se usan de manera diferente y generan valores con formatos distintos, pero todos comparten el mismo elemento HTML.

<input> es un void element: no tiene etiqueta de cierre ni contenido. Su “valor” no vive entre etiquetas como en <textarea> — vive en el atributo value, o en el estado interno del control cuando el usuario interactúa con él. Para que el valor del control viaje al servidor al enviar el formulario, el <input> debe tener un atributo name que actúa como clave en el par nombre=valor de la petición HTTP.

La validación nativa del navegador —que funciona sin JavaScript— también vive en atributos de <input>: required, minlength, maxlength, min, max, pattern, type. Cada uno agrega una restricción que el navegador verifica antes de enviar el formulario. Esta combinación de tipos y atributos de validación hace de <input> el elemento con mayor superficie de atributos de todo HTML.

el atributo type transforma el control type="text" campo libre texto type="checkbox" casilla type="range" deslizador type="color" color <input type="..."> mismo elemento — comportamiento diferente

Cómo funciona

<input> es un replaced element: el navegador lo reemplaza por un widget nativo del sistema operativo cuyo aspecto y comportamiento están definidos por el navegador, no por el HTML. Esto significa que un <input type="date"> se ve diferente en Chrome, Firefox y Safari, y distinto aún en Android vs iOS. El CSS puede ajustar tamaño, color de borde y algunos aspectos, pero el widget interno es del navegador.

Al enviarse el formulario padre, el navegador toma el valor actual del control (lo que el usuario escribió o seleccionó) y lo envía como el valor del par name=valor. Para tipos booleanos como checkbox y radio, el valor enviado es el del atributo value cuando está marcado; si no está marcado, el control directamente no se incluye en el envío.

Modelo de contenido

<input> es un void element: sin etiqueta de cierre, sin contenido. Display por defecto: inline-block. Es un elemento interactivo y debe estar asociado a un <label> para ser accesible.

Sintaxis

<!-- Void element: sin etiqueta de cierre -->
<input type="text" id="nombre" name="nombre" placeholder="Tu nombre">
<input type="email" id="correo" name="correo" required>
<input type="checkbox" id="terminos" name="terminos" value="aceptado">

Tipos (type)

El atributo type es el más importante de <input>. Su valor por defecto es text.

type="text" — texto libre

El tipo más básico. Campo de texto de una sola línea, sin restricción de formato. Acepta cualquier carácter.

<input type="text" id="nombre" name="nombre" placeholder="Tu nombre completo">

Cuándo usarlo: nombres, apellidos, títulos, cualquier dato textual que no tenga un tipo más específico.

type="email" — dirección de correo

El navegador valida que el valor tenga el formato básico de un email (texto@dominio.algo). En dispositivos móviles muestra un teclado optimizado con @ visible.

<input type="email" id="correo" name="correo" required>

Gotcha: la validación del navegador es básica (comprueba el formato, no que el email exista). El backend siempre debe revalidar.

type="password" — contraseña

Oculta los caracteres mientras el usuario escribe (los muestra como puntos o asteriscos). El valor real sí se envía al servidor.

<input type="password" id="clave" name="clave" minlength="8" required>

Importante: type="password" solo oculta visualmente. Para seguridad real, el formulario debe usar HTTPS y el backend debe hashear la contraseña antes de guardarla.

type="number" — número

Acepta solo valores numéricos. Muestra flechas de incremento/decremento (spinners). Acepta los atributos min, max y step.

<input type="number" id="edad" name="edad" min="18" max="99" step="1">

Gotcha: en algunos navegadores, type="number" con step no acepta decimales. Para valores decimales, especificá step="0.01" o step="any".

type="tel" — número de teléfono

No valida el formato (los formatos telefónicos varían demasiado por país). En móviles muestra el teclado numérico. El formato se valida con pattern.

<input type="tel" id="telefono" name="telefono" pattern="[0-9+\-\s()]{7,20}">

type="url" — URL

Valida que el valor comience con un protocolo (http://, https://, etc.). Útil para campos de sitio web.

<input type="url" id="sitio" name="sitio" placeholder="https://tusitio.com">

type="search" — búsqueda

Semánticamente igual a text, pero con estilo visual diferente en algunos navegadores (botón de borrar la búsqueda). Comunica al navegador la intención semántica del campo.

<input type="search" id="q" name="q" placeholder="Buscar...">

type="checkbox" — casilla de verificación

Crea una casilla que el usuario puede marcar o desmarcar. Cada checkbox es independiente. Cuando está marcado, envía el valor del atributo value; cuando no está marcado, el control no se incluye en el envío.

<input type="checkbox" id="terminos" name="terminos" value="aceptado">
<label for="terminos">Acepto los términos</label>

Candidato a página propia a futuro: el checkbox tiene su modelo de interacción específico (:checked, valor booleano vs value, grupos con name vs independientes), que justificaría una entrada propia si se profundiza más allá del uso básico.

type="radio" — botón de opción

Los radio buttons que comparten el mismo name forman un grupo mutuamente excluyente: solo uno puede estar seleccionado a la vez. Requieren que cada opción tenga su propio id y value.

<fieldset>
  <legend>Método de pago</legend>
  <input type="radio" id="credito" name="pago" value="credito">
  <label for="credito">Tarjeta de crédito</label>
  <input type="radio" id="debito" name="pago" value="debito">
  <label for="debito">Tarjeta de débito</label>
</fieldset>

Gotcha: radio buttons con name distintos son independientes y no se excluyen mutuamente. El error más frecuente es olvidar que el name debe ser el mismo en todos los radios del grupo.

Candidato a página propia a futuro: junto con type="checkbox", el modelo radio tiene suficiente superficie (grupos, :checked, fieldset/legend para accesibilidad) para justificar su propia entrada.

type="file" — selector de archivo

Abre el selector de archivos del sistema operativo. El formulario que lo contiene debe tener enctype="multipart/form-data" y method="post".

<form method="post" enctype="multipart/form-data">
  <input type="file" id="foto" name="foto" accept="image/*">
</form>

El atributo accept filtra los tipos de archivo que el selector muestra (no es seguridad — el filtro es del OS, el backend valida). multiple permite seleccionar varios archivos.

Candidato a página propia a futuro: type="file" tiene modelo propio (el archivo no va en value, requiere enctype, accept, multiple, consideraciones de seguridad del backend) que justifica una entrada separada.

type="date" / type="time" / type="datetime-local" — fecha y hora

Generan controles nativos del navegador para seleccionar fecha y hora. El valor se envía en formato ISO (2026-06-17). Acepta min, max y step.

<input type="date" id="nacimiento" name="nacimiento" min="1920-01-01" max="2010-12-31">
<input type="time" id="hora" name="hora">
<input type="datetime-local" id="reunion" name="reunion">

Gotcha: el aspecto del picker varía significativamente entre navegadores. En 2026 todos los navegadores modernos los soportan bien, pero para UX consistente muchas apps usan librerías JS de datepicker.

type="range" — deslizador

Renderiza un slider. El usuario arrastra para seleccionar un valor numérico. Acepta min, max y step. No muestra el valor actual por defecto — combinarlo con <output> para mostrarlo.

<input type="range" id="volumen" name="volumen" min="0" max="100" step="5" value="50">

type="color" — selector de color

Abre un picker de color. El valor se envía en formato hexadecimal (#rrggbb).

<input type="color" id="fondo" name="fondo" value="#0d9488">

type="hidden" — campo oculto

No se renderiza al usuario pero sí se incluye en el envío. Útil para pasar datos internos (tokens CSRF, IDs de registro, paso del formulario multipagina).

<input type="hidden" name="csrf_token" value="abc123xyz">

Importante: type="hidden" es invisible en la UI pero visible en el código fuente. No es un mecanismo de seguridad para datos sensibles.

type="submit" — botón de envío (inline)

Crea un botón de envío como void element. La alternativa preferida en HTML moderno es <button type="submit">, que permite contenido HTML dentro. Ver la entrada de <button>.

<input type="submit" value="Enviar formulario">

Atributos comunes

name — clave de envío

La clave del par nombre=valor en la petición HTTP. Sin name, el control no se incluye en el envío. Obligatorio en todo control que deba enviar datos.

Default: no presente.

value — valor inicial

El valor con que nace el campo. Para text/email/etc., es el texto prefijado. Para checkbox/radio, es el valor enviado cuando está marcado.

placeholder — texto de ayuda contextual

Texto gris que aparece cuando el campo está vacío y desaparece al escribir. Describe el formato esperado, no el label del campo.

<input type="email" placeholder="tu@ejemplo.com">

Gotcha: placeholder no reemplaza al <label>. El placeholder desaparece al escribir; el lector de pantalla puede no anunciarlo al entrar al campo. Usá siempre un <label> visible además del placeholder.

required — campo obligatorio

Atributo booleano. El formulario no se envía si el campo está vacío.

<input type="text" name="nombre" required>

CSS: :required para estilizar campos obligatorios; :optional para los no obligatorios.

disabled — campo deshabilitado

Atributo booleano. El control no es interactivo, no recibe foco, no puede ser editado, y su valor no se envía al servidor.

<input type="text" name="codigo" value="PRE-001" disabled>

CSS: :disabled para aplicar estilos al estado deshabilitado.

Diferencia con readonly: un campo disabled no se envía; un campo readonly sí se envía pero no puede editarse.

readonly — campo de solo lectura

El usuario puede ver y copiar el valor pero no modificarlo. A diferencia de disabled, el valor sí se incluye en el envío.

<input type="text" name="usuario" value="ana_garcia" readonly>

CSS: :read-only / :read-write.

autocomplete — autocompletar

Controla si el navegador puede sugerir valores guardados. Acepta on, off, y valores semánticos específicos (name, email, tel, new-password, etc.).

<!-- Sugiere contraseñas guardadas -->
<input type="password" name="clave" autocomplete="current-password">

<!-- Para nuevas contraseñas — impide que el gestor sugiera la actual -->
<input type="password" name="nueva-clave" autocomplete="new-password">

min / max / step — rango numérico

Para type="number", type="range", y tipos de fecha/hora. Definen el rango válido y el incremento.

<input type="number" min="0" max="100" step="5">

CSS: :in-range / :out-of-range.

pattern — expresión regular de validación

El valor debe coincidir con la regex. Aplica a campos de texto.

<!-- Solo letras y espacios -->
<input type="text" pattern="[A-Za-záéíóúÁÉÍÓÚñÑ\s]+" title="Solo letras">

El atributo title en combinación con pattern mejora el mensaje de error que muestra el navegador.

maxlength / minlength — longitud de texto

Restricciones de cantidad de caracteres para campos de texto.

<input type="text" name="usuario" minlength="3" maxlength="20">

checked — marcado por defecto

Para checkbox y radio. Marca el control como seleccionado al cargar la página.

<input type="checkbox" name="newsletter" value="si" checked>
<input type="radio" name="pais" value="argentina" checked>

multiple — múltiple selección

Para type="email" (permite ingresar varias direcciones separadas por coma) y type="file" (permite seleccionar varios archivos).

<input type="file" name="fotos" multiple accept="image/*">

accept — tipos de archivo aceptados

Solo para type="file". Filtra los archivos que muestra el selector. Acepta tipos MIME (image/*, application/pdf) o extensiones (.jpg,.png).

<input type="file" name="cv" accept=".pdf,.doc,.docx">

Estados e interacción

<input> tiene un conjunto rico de pseudoclases CSS para reflejar su estado:

PseudoclaseCuándo activa
:focusEl campo tiene el foco (teclado o clic)
:disabledEl control tiene el atributo disabled
:checkedCheckbox o radio está marcado
:requiredEl control tiene el atributo required
:optionalEl control NO tiene required
:validEl valor cumple todas las restricciones de validación
:invalidEl valor viola al menos una restricción
:placeholder-shownEl placeholder es visible (campo vacío)
:in-range / :out-of-rangePara number y range: dentro/fuera del rango
:read-only / :read-writeControl con/sin el atributo readonly
input:focus {
  outline: 2px solid #1d4ed8;
  outline-offset: 2px;
}
input:invalid {
  border-color: #dc2626;
}
input:valid {
  border-color: #16a34a;
}
input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

Gotcha con :invalid: al cargar la página, un campo required vacío ya es :invalid. Esto puede mostrar el estilo de error antes de que el usuario haya interactuado con él. Para evitar el “formulario rojo antes de empezar”, usá :user-invalid (bien soportado en 2026) o combiná con :not(:placeholder-shown):invalid.

Accesibilidad

Todo <input> visible debe tener un <label> asociado. Las dos formas:

Con for/id (recomendada): el for del label apunta al id del input.

<label for="nombre">Nombre</label>
<input type="text" id="nombre" name="nombre">

Forma envolvente: el input dentro del label crea la vinculación implícita.

<label>Nombre <input type="text" name="nombre"></label>

Sin label, el lector de pantalla anuncia el campo como “campo de texto — sin nombre”. El placeholder no reemplaza al label: desaparece al escribir y puede no ser anunciado por todos los lectores de pantalla al entrar al campo.

Para grupos de radio buttons y checkboxes relacionados, usar <fieldset> con <legend> da el contexto del grupo a los lectores de pantalla.

Cuándo usar qué tipo

Necesidadtype recomendado
Texto libre (nombre, título)text
Dirección de emailemail
Contraseñapassword
Número entero o decimalnumber
Fechadate
Horatime
Teléfonotel
URLurl
Búsquedasearch
Opción marcable independientecheckbox
Una opción de un grupo exclusivoradio
Archivo del sistemafile
Valor en rango (slider)range
Colorcolor
Dato ocultohidden

Notas, gotchas e interacción

  • name es la clave de envío, id es la clave del DOM. Son atributos distintos con propósitos distintos. El for del <label> apunta al id; el servidor recibe el name. Que tengan el mismo valor es convención, no requisito técnico.
  • Checkbox desmarcado no se envía. Si ningún checkbox de un grupo está marcado, el servidor no recibe esa clave en absoluto. Para saber que el usuario no marcó nada, se suele acompañar con un <input type="hidden" name="misma-clave" value="no">.
  • type="number" no es para todos los “números”. Números de teléfono, códigos postales y tarjetas de crédito tienen formato específico y deben usar type="tel" o type="text" con pattern, no type="number".
  • placeholderlabel. El placeholder es ayuda de formato, no el nombre del campo. Siempre hay un label visible.

Vigente / legacy

<input> está completamente vigente. Los atributos align y border (presentación inline) son legacy desde HTML5. El tipo type="image" (input de imagen como botón de submit) está en desuso para efectos prácticos — preferí un <button> con una <img> dentro. Los tipos no reconocidos por el navegador caen silenciosamente a type="text", lo que puede causar comportamiento inesperado al actualizar navegadores.