Saltar al contenido principal

Core · Campos de formulario

Campos de entrada

Un control para cada tipo de entrada: el tipo indica al navegador el teclado, el selector y la comprobación.

Esta traducción la ha escrito una IA y todavía no la ha revisado ninguna persona. Leer esta página en inglés

Cada control es un elemento nativo: el navegador se encarga del estado, el teclado, la validación y el envío, con o sin JavaScript. LUZ no marca un campo como no válido: añade .luz-input--error, aria-invalid="true" y el texto del error. Un campo envuelve un control en .luz-field:

HTML
<div class="luz-field">
  <label class="luz-field__label" for="name">Project name</label>
  <input class="luz-input" id="name" type="text" aria-describedby="name-hint name-error">
  <div class="luz-field__helper" id="name-hint">Shown on the dashboard.</div>
  <div class="luz-field__error" id="name-error"><span class="u-sr-only">Error: </span>Use letters, numbers and dashes only.</div>
</div>

Texto

Un campo de una línea para una respuesta corta que no puedes enumerar de antemano, como un nombre.

Shown on the dashboard.
Error: Use letters, numbers and dashes only.

Código

Copiar el marcado

Una etiqueta y un campo no necesitan ninguna clase. .luz-field añade una pista y un error:

HTML
<div class="luz-field">
  <label class="luz-field__label" for="name">Project name</label>
  <input class="luz-input" id="name" type="text" aria-describedby="name-hint">
  <div class="luz-field__helper" id="name-hint">Shown on the dashboard.</div>
</div>

Variantes y opciones

  • required, con .luz-field__label--required para el asterisco rojo.
  • Error: .luz-input--error, aria-invalid="true" y un .luz-field__error después del campo.
  • disabled: atenuado, la tecla Tab lo salta y no se envía.
  • readonly: subrayado discontinuo, se puede alcanzar y se envía.
  • list con un <datalist>: sugerencias que el lector puede ignorar.

Cómo funciona

Un <input> nativo con el estilo de components/form.css. LUZ no marca un campo como no válido por ti: añade la clase de error, aria-invalid y el mensaje cuando falle tu validación.

Sin JavaScript

El campo funciona y se envía con su formulario.

Teclado y ARIA

  • Tab lleva el foco al campo y Shift+Tab lo saca.
  • La etiqueta es el nombre; la pista y el error se leen después. Un marcador de posición no es un nombre.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de texto para una respuesta corta que no puedes enumerar de antemano.

  • Un nombre, un título, un código, una referencia.
  • Una dirección, un número o una fecha: usa el campo de ese type, como correo electrónico, número o fecha.

Cuándo no usarlo

No hagas escribir al lector lo que podría elegir.

Qué hacer y qué no

Hazlo Una etiqueta visible: sigue en pantalla mientras el lector escribe.
Evítalo Un marcador de posición como etiqueta: desaparece cuando el lector escribe.

Cómo escribir el contenido

  • La etiqueta es un sustantivo corto en minúsculas, salvo la inicial: «Nombre del proyecto».
  • La pista dice el formato o por qué lo pides.
  • El error dice qué está mal y cómo corregirlo.

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Correo electrónico

Un campo para una dirección de correo electrónico: el navegador comprueba su forma y los teléfonos muestran la arroba.

We send your receipt here.

Código

Copiar el marcado

Un campo de texto con type="email"; autocomplete="email" deja que el navegador lo rellene.

HTML
<div class="luz-field">
  <label class="luz-field__label" for="email">Email</label>
  <input class="luz-input" id="email" type="email" autocomplete="email" required aria-describedby="email-hint">
  <div class="luz-field__helper" id="email-hint">We send your receipt here.</div>
</div>

Variantes y opciones

  • multiple: varias direcciones, separadas por comas.
  • Las clases y los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <input type="email"> nativo. El navegador comprueba la forma al enviar el formulario, no que la dirección exista.

Sin JavaScript

El navegador comprueba la dirección al enviar el formulario, sin ningún script.

Teclado y ARIA

  • Tab lleva el foco al campo y Shift+Tab lo saca. En un teléfono, el teclado muestra la arroba.
  • La etiqueta es el nombre; la pista y el error se leen después.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de correo electrónico siempre que la respuesta sea una dirección de correo.

  • Registrarse, iniciar sesión, formularios de contacto y recibos.
  • Di en la pista para qué sirve la dirección.

Cuándo no usarlo

Un campo de correo electrónico comprueba la forma de una dirección, no que funcione.

  • No uses un campo de texto para una dirección: el lector pierde la comprobación y el teclado.
  • No cuentes con él para demostrar que la dirección es real: envía un mensaje y pide confirmación.

Qué hacer y qué no

Hazlo Un error que explica cómo corregir la dirección.
Evítalo Un error que solo dice que algo está mal.

Cómo escribir el contenido

  • Ponle la etiqueta «Correo electrónico», no «Escribe aquí tu dirección de correo electrónico».
  • La pista dice para qué se usa la dirección.
  • El error dice qué cambiar: una dirección tiene una @ y un dominio.

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Contraseña

Un campo que oculta lo que se escribe, para una contraseña u otro secreto.

At least 8 characters.

Código

Copiar el marcado

Un campo de texto con type="password". Usa autocomplete para decir qué es el campo:

HTML
<div class="luz-field">
  <label class="luz-field__label luz-field__label--required" for="password">Password</label>
  <input class="luz-input" id="password" type="password" autocomplete="current-password" minlength="8" required aria-describedby="password-hint">
  <div class="luz-field__helper" id="password-hint">At least 8 characters.</div>
</div>

Variantes y opciones

  • autocomplete="current-password" para iniciar sesión; "new-password" para registrarse o cambiarla.
  • minlength, maxlength, pattern: el navegador los comprueba al enviar el formulario.
  • Los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <input type="password"> nativo con el estilo de cualquier campo de texto. El navegador dibuja puntos en lugar de los caracteres. LUZ no añade un botón para mostrar la contraseña: el que añadas es tu propio script.

Sin JavaScript

El campo funciona y se envía con su formulario.

Teclado y ARIA

  • Tab lleva el foco al campo y Shift+Tab lo saca.
  • La etiqueta es el nombre; la pista dice las reglas antes de que el lector escriba. No bloquees el pegado: los lectores pegan contraseñas largas.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de contraseña para cualquier secreto que el lector escribe y que no debe verse en pantalla.

  • Iniciar sesión, registrarse y cambiar una contraseña.
  • Pon en autocomplete el valor current-password o new-password.

Cuándo no usarlo

Un campo de contraseña es para secretos, no para cualquier código.

  • Un código enviado por mensaje de texto o por correo: un campo de texto con inputmode="numeric" y autocomplete="one-time-code".
  • Algo que el lector debe ver para comprobarlo, como una dirección: un campo de texto.

Qué hacer y qué no

Hazlo Di qué es el campo: current-password para iniciar sesión, new-password para registrarse.
Evítalo Un campo de texto para un secreto: muestra lo que se escribe a cualquiera que mire la pantalla.

Cómo escribir el contenido

  • Ponle la etiqueta «Contraseña», no «Escribe tu contraseña».
  • La pista indica las reglas antes de que el lector escriba: «Al menos 8 caracteres.»
  • El error dice qué falta: «Usa al menos 8 caracteres.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Un campo de texto para las palabras que se buscan, con una tecla de búsqueda en los teclados de teléfono y un botón para borrar en algunos navegadores.

Search by name or topic.

Código

Copiar el marcado

Un campo de texto con type="search" dentro de un formulario con role="search", de modo que la página tiene un punto de referencia de búsqueda:

HTML
<form role="search">
  <div class="luz-field">
    <label class="luz-field__label" for="search">Search the docs</label>
    <input class="luz-input" id="search" type="search" name="q" enterkeyhint="search" aria-describedby="search-hint">
    <div class="luz-field__helper" id="search-hint">Search by name or topic.</div>
  </div>
  <button type="submit">Search</button>
</form>

Variantes y opciones

  • enterkeyhint="search": la tecla Enter de un teclado de teléfono dice «Buscar».
  • list con un <datalist>: sugerencias que el lector puede ignorar.
  • Los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <input type="search"> nativo con el estilo de cualquier campo de texto. Algunos navegadores añaden dentro un botón que lo borra; ese botón es del navegador y LUZ no lo dibuja.

Sin JavaScript

Enter envía el formulario, como una petición a la dirección de tu búsqueda. No hace falta ningún script.

Teclado y ARIA

  • Tab lleva el foco al campo. Enter envía la búsqueda.
  • La etiqueta es el nombre; la pista y el error se leen después. Un marcador de posición no es un nombre.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de búsqueda para encontrar algo por palabras, en una lista, una página o un sitio.

  • Un filtro sobre una tabla o una lista.
  • Para todo el sitio, usa la búsqueda, que tiene un diálogo y un índice.

Cuándo no usarlo

No uses un campo de búsqueda para una respuesta que es un nombre o un título.

  • Un nombre, un título o una referencia: un campo de texto.
  • Una elección que el lector puede enumerar: un selector o botones de radio.

Qué hacer y qué no

Hazlo Una etiqueta visible que dice qué se busca.
Evítalo Un marcador de posición como único nombre: desaparece cuando el lector escribe.

Cómo escribir el contenido

  • La etiqueta dice qué se busca: «Buscar en la documentación».
  • El botón es un verbo: «Buscar».
  • Si no hay resultados, dilo y ofrece una salida: «Sin resultados para “formularios”. Prueba con menos palabras.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Teléfono

Un campo para un número de teléfono: los teléfonos muestran un teclado numérico y el navegador no comprueba ningún formato.

With the country code, such as +34 600 000 000.

Código

Copiar el marcado

Un campo de texto con type="tel"; autocomplete="tel" deja que el navegador lo rellene:

HTML
<div class="luz-field">
  <label class="luz-field__label" for="tel">Phone</label>
  <input class="luz-input" id="tel" type="tel" autocomplete="tel" aria-describedby="tel-hint">
  <div class="luz-field__helper" id="tel-hint">With the country code, such as +34 600 000 000.</div>
</div>

Variantes y opciones

  • autocomplete="tel": el navegador rellena el número del lector.
  • pattern: solo cuando conoces el formato, con un error que lo diga; el navegador no comprueba nada más.
  • Los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <input type="tel"> nativo. Los números de teléfono varían según el país, así que el navegador solo elige el teclado y no comprueba ningún formato. Comprueba el número en el servidor.

Sin JavaScript

El campo funciona y envía su texto con el formulario.

Teclado y ARIA

  • Tab lleva el foco al campo y Shift+Tab lo saca. En un teléfono, el teclado es un teclado numérico.
  • La etiqueta es el nombre; la pista dice el formato que aceptas y el error dice qué cambiar.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de teléfono siempre que la respuesta sea un número de teléfono.

  • Formularios de contacto, de entrega y de reserva.
  • Di en la pista si hace falta el prefijo del país, o acepta cualquier formato y ordénalo en el servidor.

Cuándo no usarlo

Un campo de teléfono no comprueba nada, y no es para cualquier número.

  • Una cantidad que el lector suma: un campo de número.
  • Un código o una referencia hecha de dígitos: un campo de texto con inputmode="numeric".

Qué hacer y qué no

Hazlo Una pista que muestra el formato que aceptas.
Evítalo Un patrón de diez dígitos: se rechaza un número escrito con un signo más o con espacios.

Cómo escribir el contenido

  • Ponle la etiqueta «Teléfono», no «Número de teléfono (solo dígitos)».
  • La pista da un ejemplo del formato.
  • El error dice qué cambiar: «Escribe un número de teléfono con el prefijo del país.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

URL

Un campo para una dirección web: el navegador comprueba que lleve un esquema como https:// y los teléfonos muestran una tecla de barra.

Start with https://.

Código

Copiar el marcado

Un campo de texto con type="url"; autocomplete="url" deja que el navegador lo rellene:

HTML
<div class="luz-field">
  <label class="luz-field__label" for="url">Website</label>
  <input class="luz-input" id="url" type="url" autocomplete="url" placeholder="https://example.com" aria-describedby="url-hint">
  <div class="luz-field__helper" id="url-hint">Start with https://.</div>
</div>

Variantes y opciones

  • pattern="https://.*": solo direcciones seguras.
  • list con un <datalist>: sugerencias que el lector puede ignorar.
  • Los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <input type="url"> nativo. Al enviar el formulario, el navegador comprueba que el valor sea una dirección completa con esquema: https://example.com pasa, example.com no. Acepta cualquier esquema, así que, antes de convertir el valor en un enlace, comprueba en el servidor que sea http o https.

Sin JavaScript

El navegador comprueba la dirección al enviar el formulario, sin ningún script.

Teclado y ARIA

  • Tab lleva el foco al campo y Shift+Tab lo saca. En un teléfono, el teclado muestra la barra y el punto.
  • La etiqueta es el nombre; la pista dice que la dirección empieza por https://.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de URL cuando la respuesta sea la dirección de una página o de un sitio.

  • Un sitio web, un perfil o un portafolio.
  • Di en la pista que la dirección empieza por https://: el navegador rechaza una sin esquema.

Cuándo no usarlo

Un campo de URL solo admite una dirección completa, y no demuestra nada sobre el sitio.

  • Una ruta como /docs/start: un campo de texto.
  • No te fíes del valor: el navegador no comprueba que el sitio exista ni que sea seguro.

Qué hacer y qué no

Hazlo Di en la pista que la dirección empieza por https://.
Evítalo Un campo de URL para una ruta: el navegador la rechaza.

Cómo escribir el contenido

  • Ponle la etiqueta «Sitio web», no «Escribe la URL de tu sitio web».
  • La pista dice cómo empieza: «Empieza por https://.»
  • El error dice qué cambiar: «Escribe una dirección completa, que empiece por https://.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Número

Un campo para una cantidad que se cuenta o se ajusta por pasos, con botones de incremento y una comprobación de rango.

From 1 to 10.

Código

Copiar el marcado

Un campo de texto con type="number"; min, max y step fijan lo que es válido:

HTML
<div class="luz-field">
  <label class="luz-field__label" for="number">Quantity</label>
  <input class="luz-input" id="number" type="number" min="1" max="10" step="1" value="1" aria-describedby="number-hint">
  <div class="luz-field__helper" id="number-hint">From 1 to 10.</div>
</div>

Variantes y opciones

  • min, max: se comprueban al enviar el formulario y son los límites de los botones de incremento.
  • step: el tamaño de un paso; step="any" permite decimales.
  • Los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <input type="number"> nativo. El navegador añade botones de incremento, envía el valor escrito con punto y comprueba min, max y step al enviar el formulario. Los botones de incremento son del navegador: LUZ no les da estilo.

Sin JavaScript

El navegador comprueba el número al enviar el formulario, sin ningún script.

Teclado y ARIA

  • Tab lleva el foco al campo. Las flechas arriba y abajo suman o restan un paso.
  • La etiqueta es el nombre; di el rango en la pista.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de número para una cantidad: algo que el lector cuenta, suma o resta.

  • Artículos en una cesta, invitados, plazas.
  • Fija min, max y step para que la comprobación y los botones de incremento coincidan.

Cuándo no usarlo

Un campo de número es para cantidades, no para cualquier valor hecho de dígitos.

  • Un código postal, una tarjeta o un código de un solo uso: un campo de texto con inputmode="numeric".
  • Un valor aproximado en una escala: un rango.

Qué hacer y qué no

Hazlo Un campo de número para una cantidad, con sus límites en la pista.
Evítalo Un campo de número para un código postal: no es una cantidad, y sus botones de incremento le sumarían uno.

Cómo escribir el contenido

  • Ponle una etiqueta según lo que se cuenta: «Cantidad», «Invitados».
  • Pon la unidad en la etiqueta o en la pista: «Peso, en kg».
  • El error dice los límites: «Escribe un número del 1 al 10.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Fecha

Un campo para una fecha del calendario, con el selector propio del navegador. El valor es siempre año-mes-día.

Pick a day in 2026.

Código

Copiar el marcado

Un campo de texto con type="date"; min y max limitan los días:

HTML
<div class="luz-field">
  <label class="luz-field__label" for="date">Start date</label>
  <input class="luz-input" id="date" type="date" min="2026-01-01" max="2026-12-31" aria-describedby="date-hint">
  <div class="luz-field__helper" id="date-hint">Pick a day in 2026.</div>
</div>

Variantes y opciones

  • min, max: los días fuera de ellos se rechazan y aparecen atenuados en el selector.
  • step: el paso en días.
  • Los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <input type="date"> nativo. Muestra la fecha en el idioma y el orden del lector, y siempre envía yyyy-mm-dd. El selector es del navegador; su esquema claro u oscuro sigue el modo de color de la página.

Sin JavaScript

El campo funciona y se envía con su formulario. Si un navegador que admites no tiene selector de fechas, muestra un campo de texto: di el formato en la pista.

Teclado y ARIA

  • Las teclas del propio selector del navegador son las que se aplican.
  • La etiqueta es el nombre; la pista dice los límites.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de fecha para un día que el lector pueda elegir en un calendario, cerca de hoy.

  • Una reserva, un plazo o un día de entrega.
  • Fija min y max para que el selector solo ofrezca días válidos.

Cuándo no usarlo

Recorrer un calendario es lento para una fecha lejana a hoy.

  • Una fecha de nacimiento, o cualquier fecha de hace décadas: tres campos, un número para el día, un selector para el mes y un número para el año.
  • Un mes y un año solos: un campo de mes.

Qué hacer y qué no

Hazlo Un campo de fecha con sus límites en la pista.
Evítalo Un campo de texto para una fecha: cada lector adivina el orden del día y del mes.

Cómo escribir el contenido

  • Ponle una etiqueta según lo que es la fecha: «Fecha de inicio», «Fecha de entrega».
  • La pista dice los límites, no el formato: el selector ya tiene uno.
  • El error dice qué cambiar: «Elige un día de 2026.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Hora

Un campo para una hora del día, en el reloj de 12 o 24 horas del lector, como horas y minutos.

Your local time.

Código

Copiar el marcado

Un campo de texto con type="time":

HTML
<div class="luz-field">
  <label class="luz-field__label" for="time">Reminder</label>
  <input class="luz-input" id="time" type="time" value="09:00" aria-describedby="time-hint">
  <div class="luz-field__helper" id="time-hint">Your local time.</div>
</div>

Variantes y opciones

  • min, max: la hora más temprana y la más tardía.
  • step: en segundos; step="1" añade segundos, step="900" avanza de cuarto en cuarto de hora.
  • Los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <input type="time"> nativo. Muestra la hora en el reloj del lector, de 12 o de 24 horas, y siempre envía hh:mm. El valor no lleva zona horaria.

Sin JavaScript

El campo funciona y se envía con su formulario. Si un navegador que admites no tiene selector de horas, muestra un campo de texto: di el formato en la pista.

Teclado y ARIA

  • Las teclas del propio selector del navegador son las que se aplican.
  • La etiqueta es el nombre; la pista dice la zona horaria.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de hora para una hora del día: un horario de apertura, una alarma, una cita.

  • Di la zona horaria en la pista: el campo no la tiene.
  • Usa dos campos, una fecha y una hora, cuando el lector pueda elegirlas por separado.

Cuándo no usarlo

Un campo de hora es una hora del día, no una duración.

  • Una duración, como 90 minutos: un campo de número con su unidad en la etiqueta.
  • Un día y una hora juntos: fecha y hora.

Qué hacer y qué no

Hazlo Di en qué zona horaria está la hora.
Evítalo Un campo de texto para una hora: 9, 9am y 09:00 significan lo mismo para el lector y no para tu código.

Cómo escribir el contenido

  • Ponle una etiqueta según lo que es la hora: «Hora de apertura», «Recordatorio».
  • La pista dice la zona horaria: «Hora de Madrid.»
  • El error dice los límites: «Elige una hora entre las 09:00 y las 18:00.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Fecha y hora

Un campo para un día y una hora juntos. El valor no lleva zona horaria.

Madrid time.

Código

Copiar el marcado

Un campo de texto con type="datetime-local"; di la zona horaria en la pista:

HTML
<div class="luz-field">
  <label class="luz-field__label" for="datetime-local">Meeting starts</label>
  <input class="luz-input" id="datetime-local" type="datetime-local" min="2026-01-01T08:00" aria-describedby="datetime-local-hint">
  <div class="luz-field__helper" id="datetime-local-hint">Madrid time.</div>
</div>

Variantes y opciones

  • min, max: el momento más temprano y el más tardío, como yyyy-mm-ddThh:mm.
  • step: en segundos, como en el campo de hora.
  • Los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <input type="datetime-local"> nativo. «Local» significa el reloj del propio lector: envía yyyy-mm-ddThh:mm sin zona horaria. Di la zona en la pista, o guarda la zona junto al valor en el servidor.

Sin JavaScript

El campo funciona y se envía con su formulario. Si un navegador que admites no tiene selector para él, muestra un campo de texto: di el formato en la pista.

Teclado y ARIA

  • Las teclas del propio selector del navegador son las que se aplican.
  • La etiqueta es el nombre; la pista dice la zona horaria.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de fecha y hora para un momento que el lector elige, en un solo lugar.

  • El inicio de un evento, una reserva o un recordatorio.
  • Di la zona horaria en la pista: el valor no la tiene.

Cuándo no usarlo

El valor no lleva zona horaria, así que no puede decir a qué momento corresponde un evento para lectores de otras zonas.

  • Un día solo: un campo de fecha. Una hora sola: un campo de hora.
  • Una lista corta de franjas: botones de radio con las horas.

Qué hacer y qué no

Hazlo Di en qué zona horaria está el momento.
Evítalo Una pista que omite la zona horaria: un lector de otra zona lee un momento distinto.

Cómo escribir el contenido

  • Ponle una etiqueta según el momento: «La reunión empieza», «Entrega antes de».
  • La pista nombra la zona horaria: «Hora de Madrid.»
  • El error dice qué cambiar: «Elige un momento posterior a las 8:00.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Mes

Un campo para un mes y un año, como la caducidad de una tarjeta. El valor es año-mes.

Month and year, such as 2026-06.

Código

Copiar el marcado

Un campo de texto con type="month". El marcador de posición y el patrón son para un navegador que muestra un campo de texto en su lugar:

HTML
<div class="luz-field">
  <label class="luz-field__label" for="month">Billing month</label>
  <input class="luz-input" id="month" type="month" min="2026-01" max="2026-12" placeholder="YYYY-MM" pattern="[0-9]{4}-[0-9]{2}" aria-describedby="month-hint">
  <div class="luz-field__helper" id="month-hint">Month and year, such as 2026-06.</div>
</div>

Variantes y opciones

  • min, max: el primer mes y el último, como yyyy-mm.
  • step: en meses.
  • Los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <input type="month"> nativo que envía yyyy-mm. Comprueba los navegadores que admites: uno sin selector de meses muestra un campo de texto. Un navegador con selector ignora placeholder y pattern, y uno sin él los usa.

Sin JavaScript

El campo funciona y se envía con su formulario, como selector o como campo de texto.

Teclado y ARIA

  • Se aplican las teclas del propio selector del navegador; en un campo de texto, escribe yyyy-mm.
  • La etiqueta es el nombre; la pista dice el formato, para los navegadores con un campo de texto.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de mes cuando solo importan el mes y el año.

  • La caducidad de una tarjeta, un mes de facturación o un periodo de un informe.
  • Di el formato en la pista, para los navegadores que muestran un campo de texto.

Cuándo no usarlo

Un campo de mes no tiene día, así que no puede contener una fecha.

  • Un día: un campo de fecha.
  • Una lista corta de meses, para un lector cuyo navegador no tiene selector: un selector para el mes y un número para el año.

Qué hacer y qué no

Hazlo Pide un mes y un año cuando no hace falta un día.
Evítalo Un campo de fecha cuando solo importa el mes: pide un día que el lector puede no tener.

Cómo escribir el contenido

  • Ponle una etiqueta según lo que es el mes: «Mes de facturación», «Caducidad».
  • La pista da el formato: «Mes y año, como 2026-06.»
  • El error dice qué cambiar: «Escribe un mes y un año, como 2026-06.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Semana

Un campo para una semana de un año, como 2026-W24, para planificar por semanas.

Week of the year, such as 2026-W24. Weeks start on Monday.

Código

Copiar el marcado

Un campo de texto con type="week". El marcador de posición y el patrón son para un navegador que muestra un campo de texto en su lugar:

HTML
<div class="luz-field">
  <label class="luz-field__label" for="week">Sprint week</label>
  <input class="luz-input" id="week" type="week" min="2026-W01" max="2026-W52" placeholder="YYYY-Www" pattern="[0-9]{4}-W[0-9]{2}" aria-describedby="week-hint">
  <div class="luz-field__helper" id="week-hint">Week of the year, such as 2026-W24. Weeks start on Monday.</div>
</div>

Variantes y opciones

  • min, max: la primera semana y la última, como yyyy-Www.
  • step: en semanas.
  • Los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <input type="week"> nativo que envía yyyy-Www, con las semanas contadas como lo hace ISO 8601: empiezan en lunes. Comprueba los navegadores que admites: uno sin selector de semanas muestra un campo de texto y usa placeholder y pattern.

Sin JavaScript

El campo funciona y se envía con su formulario, como selector o como campo de texto.

Teclado y ARIA

  • Se aplican las teclas del propio selector del navegador; en un campo de texto, escribe yyyy-Www.
  • La etiqueta es el nombre; la pista dice cómo se cuentan las semanas.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de semana cuando el lector planifica o informa por semana del año.

  • Una hoja de horas, un sprint o un calendario de entregas.
  • Di en la pista que las semanas empiezan en lunes.

Cuándo no usarlo

La mayoría de los lectores no sabe en qué semana del año está.

  • Un día: un campo de fecha, y calcula la semana en el servidor.
  • Un intervalo de días: dos campos de fecha, un inicio y un fin.

Qué hacer y qué no

Hazlo Di cómo se cuentan las semanas: empiezan en lunes.
Evítalo Pedir a un público general un número de semana: pocos lectores lo saben.

Cómo escribir el contenido

  • Ponle una etiqueta según lo que es la semana: «Semana del sprint», «Semana de entrega».
  • La pista da el formato y el primer día de la semana.
  • El error dice qué cambiar: «Escribe una semana, como 2026-W24.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Color

Una muestra que abre el selector de color del sistema. El valor es un color hexadecimal, #rrggbb.

Código

Copiar el marcado

La clase .luz-input es la que dibuja la muestra: un campo de color sin clase conserva el aspecto del propio navegador.

HTML
<div class="luz-field">
  <label class="luz-field__label" for="color">Accent colour</label>
  <input class="luz-input" id="color" type="color" value="#0066cf">
</div>

Variantes y opciones

  • value: el color inicial. Sin él, la muestra es negra (#000000).
  • disabled: atenuado, la tecla Tab lo salta y no se envía.
  • Las clases y el error son los del campo de texto.

Cómo funciona

Un <input type="color"> nativo con .luz-input[type="color"]: una muestra de 64 px con el borde inferior del campo. El valor es siempre hexadecimal en minúsculas, #rrggbb, sin transparencia ni nombre. El selector es el del sistema.

Sin JavaScript

El campo funciona y envía su valor hexadecimal con el formulario.

Teclado y ARIA

  • Tab lleva el foco a la muestra. Enter o Espacio abre el selector, cuyas teclas son las del sistema.
  • La etiqueta es el nombre. Una muestra es solo un color: escribe el valor como texto donde el lector lo necesite.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de color cuando el lector pueda elegir cualquier color: una etiqueta, una marca o un gráfico.

  • Empieza con value, para que la muestra no sea negra.
  • Comprueba por tu parte el contraste del color: el selector permite cualquiera.

Cuándo no usarlo

Un campo de color es para una elección libre, no para una lista corta.

  • Unos pocos colores con nombre: botones de radio con los nombres.
  • Un color que fija tu diseño: no se lo preguntes al lector.

Qué hacer y qué no

Hazlo Un campo de color para una elección libre, con una etiqueta que dice qué colorea.
Evítalo Un campo de color para elegir entre tres colores: los botones de radio con sus nombres dicen cuál es cuál.

Cómo escribir el contenido

  • Ponle una etiqueta según lo que colorea: «Color de acento», «Color de la etiqueta».
  • Nombra el color donde importe: una muestra sola no dice nada a algunos lectores.
  • El error dice qué cambiar: «Elige un color más oscuro.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Archivo

Un botón que abre el selector de archivos del sistema y el nombre del archivo elegido.

PDF or PNG, up to 5 MB.

Código

Copiar el marcado

La clase .luz-input da estilo al botón y al nombre. El formulario necesita enctype="multipart/form-data" para enviar el archivo:

HTML
<form method="post" enctype="multipart/form-data">
  <div class="luz-field">
    <label class="luz-field__label" for="file">Attachment</label>
    <input class="luz-input" id="file" type="file" accept=".pdf,.png" aria-describedby="file-hint">
    <div class="luz-field__helper" id="file-hint">PDF or PNG, up to 5 MB.</div>
  </div>
  <button type="submit">Upload</button>
</form>

Variantes y opciones

  • accept: los tipos que ofrece el selector, como .pdf o image/*.
  • multiple: varios archivos; required: el navegador detiene el formulario hasta que se elige uno.
  • Los estados de error y desactivado son los del campo de texto.

Cómo funciona

Un <input type="file"> nativo. .luz-input[type="file"] da estilo al botón con tokens (::file-selector-button). Sus textos, «Choose file» y «No file chosen», son del navegador, en el idioma del lector. accept solo filtra el selector: comprueba el tipo y el tamaño en el servidor.

Sin JavaScript

El campo funciona y envía su archivo con el formulario, con method="post" y enctype="multipart/form-data".

Teclado y ARIA

  • Tab lleva el foco al botón. Enter o Espacio abre el selector.
  • La etiqueta es el nombre; la pista dice los tipos y el tamaño.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un campo de archivo cuando el lector envía un archivo desde su propio dispositivo.

  • Un currículum, una foto o un adjunto.
  • Di los tipos aceptados y el tamaño en la pista, antes de que el lector elija.

Cuándo no usarlo

Un campo de archivo no puede comprobar lo que recibe.

  • No cuentes con accept para la seguridad: filtra el selector, y un lector puede elegir cualquier cosa. Comprueba en el servidor.
  • La dirección de un archivo que ya está en línea: un campo de URL.

Qué hacer y qué no

Hazlo Di los tipos y el tamaño en la pista, antes de que el lector elija.
Evítalo Un campo de archivo sin pista: el lector descubre los límites cuando falla la subida.

Cómo escribir el contenido

  • Ponle una etiqueta con un sustantivo: «Adjunto», «Foto».
  • La pista da los tipos y el tamaño: «PDF o PNG, de hasta 5 MB.»
  • El error dice qué cambiar: «El archivo supera los 5 MB. Elige uno más pequeño.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Rango

Un deslizador para un valor en una escala, donde la posición del control importa más que el número exacto.

Código

Copiar el marcado

Un deslizador con min, max y step, y un <output> que muestra su valor. El deslizador no muestra ningún número propio, así que unas pocas líneas de tu propio script actualizan el resultado:

HTML
<div class="luz-field">
  <label class="luz-field__label" for="volume">Volume <output class="luz-output" id="volume-out" for="volume">50</output></label>
  <input class="luz-input" id="volume" type="range" min="0" max="100" value="50">
</div>
JS
const range = document.getElementById("volume");
const output = document.getElementById("volume-out");
range.addEventListener("input", () => {
  output.value = range.value;
});

Variantes y opciones

  • min, max, step: la escala y el tamaño de un paso.
  • disabled: atenuado, la tecla Tab lo salta y no se envía. Un rango no tiene estado de solo lectura.
  • Sin un <output>, el lector no puede ver el número: añade siempre uno.

Cómo funciona

Un <input type="range"> nativo. .luz-input[type="range"] asigna a accent-color el valor --luz-brand-primary, así que el control y la pista rellena siguen la marca. LUZ no tiene ningún script para el resultado: el tuyo escucha el evento input.

Sin JavaScript

El deslizador funciona y envía su valor. Sin tu script, el resultado sigue mostrando el valor inicial.

Teclado y ARIA

  • Tab lleva el foco al deslizador. Izquierda y abajo restan un paso, derecha y arriba suman uno. Inicio y Fin van a los extremos.
  • La etiqueta es el nombre; une el resultado al deslizador con for.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un rango cuando el lector fija un valor a ojo y basta una respuesta aproximada.

  • El volumen, el brillo o un presupuesto aproximado.
  • Muestra el valor junto al deslizador y fija min, max y step según lo que necesites.

Cuándo no usarlo

No uses un rango cuando importa el número exacto o la escala es larga.

  • Una cantidad exacta: un campo de número.
  • Unos pocos niveles con nombre: botones de radio con los nombres.

Qué hacer y qué no

Hazlo Muestra el valor como texto junto al deslizador.
Evítalo Un deslizador sin valor: el lector no sabe qué ha fijado.

Cómo escribir el contenido

  • Ponle una etiqueta según lo que fija: «Volumen», «Brillo».
  • El resultado contiene solo el número; pon la unidad en la etiqueta: «Volumen, %».
  • Di en la pista los extremos de la escala si no son obvios.

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Área de texto

Un campo para texto de más de una línea, como un mensaje o una descripción.

Up to 500 characters.

Código

Copiar el marcado

Un <textarea> nativo. .luz-input--textarea le da su altura, y maxlength su límite:

HTML
<div class="luz-field">
  <label class="luz-field__label" for="textarea">Message</label>
  <textarea class="luz-input luz-input--textarea" id="textarea" rows="4" maxlength="500" aria-describedby="textarea-hint"></textarea>
  <div class="luz-field__helper" id="textarea-hint">Up to 500 characters.</div>
</div>

Variantes y opciones

  • rows: la altura inicial; el lector puede estirarlo hacia abajo, nunca más ancho.
  • maxlength, minlength: el navegador los comprueba; di el límite en la pista.
  • Los estados son los del campo de texto: error, obligatorio, desactivado y de solo lectura.

Cómo funciona

Un <textarea> nativo con el estilo de un campo de texto, de al menos 80 px de alto. Un área de texto sin clase se ve igual. LUZ no tiene contador de caracteres.

Sin JavaScript

El campo funciona y se envía con su formulario.

Teclado y ARIA

  • Tab lleva el foco al campo y lo saca. Enter añade una línea nueva: no envía el formulario.
  • La etiqueta es el nombre; la pista dice el límite.

El contraste y el foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Usa un área de texto para texto libre de más de una línea.

  • Un mensaje, un comentario, una descripción o una biografía.
  • Di el límite en la pista, si lo hay.

Cuándo no usarlo

No uses un área de texto para una respuesta corta ni para texto con formato.

  • Un nombre, un título o una referencia: un campo de texto.
  • Texto con títulos y enlaces: tu propio editor. No construyas nunca un área de texto con un <div contenteditable>.

Qué hacer y qué no

Hazlo Un área de texto para un mensaje, con su límite en la pista.
Evítalo Un área de texto para un nombre: invita a escribir un ensayo y ocupa el espacio de un párrafo.

Cómo escribir el contenido

  • Ponle una etiqueta según lo que hay que escribir: «Mensaje», «Descripción».
  • La pista da el límite: «Hasta 500 caracteres.»
  • El error dice qué cambiar: «Escribe al menos 20 caracteres.»

Contraste y foco

Compartido con los demás campos: contraste y foco de los campos.

Tokens que usa

Compartido con los demás campos: tokens de los campos.

El teclado y ARIA están en la pestaña Código.

Contraste y foco de los campos

La etiqueta y la pista son texto secundario de la página; lo que escribe el lector es texto principal sobre el campo. El deslizador de rango y el botón de archivo tienen sus propios pares.

ParteColor sobre el fondoClaroOscuroAlto contrasteMínimo
Etiqueta
--luz-text-secondary on --luz-surface-page
6.2:1
7.5:1
19.3:1
4.5:1
Texto escrito
--luz-text-primary on --luz-input-bg
16.5:1
14.0:1
21.0:1
4.5:1
Marcador de posición
--luz-text-muted on --luz-input-bg
5.1:1
5.2:1
9.0:1
4.5:1
Mensaje de error
--luz-color-danger on --luz-surface-page
5.3:1
11.7:1
9.3:1
4.5:1
Borde inferior del campo y borde de la muestra de color
--luz-input-border on --luz-input-bg
3.9:1
3.9:1
21.0:1
3:1
Borde de error
--luz-color-danger on --luz-input-bg
5.5:1
10.8:1
9.3:1
3:1
Texto desactivado
--luz-text-disabled on --luz-input-bg
3.7:1
3.9:1
5.3:1
3:1
Control y pista rellena del rango
--luz-brand-primary on --luz-surface-page
5.6:1
7.7:1
14.1:1
3:1
Nombre del archivo
--luz-text-secondary on --luz-input-bg
6.4:1
6.9:1
19.3:1
4.5:1
Texto del botón de archivo
--luz-text-primary on --luz-surface-strong
13.5:1
10.9:1
18.0:1
4.5:1
Texto del botón de archivo al pasar el puntero
--luz-text-primary on --luz-surface-hover
14.4:1
12.6:1
20.1:1
4.5:1
Anillo de foco
--luz-focus-ring on --luz-surface-page
5.6:1
7.7:1
21.0:1
3:1

Medido a partir de los valores de los tokens de cada modo y redondeado hacia abajo. El mínimo requerido es el de WCAG 2.2 AA: 4,5:1 para texto y 3:1 para anillos de foco, bordes e iconos.

  • Foco: un contorno de 2 px --luz-focus-ring, a 2 px fuera del campo (a 4 px fuera de un deslizador de rango); el borde inferior de un campo también adopta el color del anillo.
  • No depende solo del color: un campo no válido tiene un borde inferior de 2 px y un mensaje con palabras; uno de solo lectura o desactivado lo tiene discontinuo. Escribe el valor de un campo de color como texto.
  • Objetivo táctil: un campo mide 44 px de alto.

Tokens de los campos

Los 25 tokens que leen las reglas de estos controles, agrupados por familia. Cada familia enlaza a su página, donde aparecen los valores de todos los modos.

Spacing and sizing
--luz-control-lg, --luz-control-md, --luz-space-2xs, --luz-space-3xs, --luz-space-md, --luz-space-sm, --luz-space-xs
Typography
--luz-font-sans, --luz-text-control, --luz-text-md, --luz-text-sm
Radius
--luz-radius-md
Motion
--luz-duration-base, --luz-duration-fast

Problemas conocidos

Ninguno conocido.