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.
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:
<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.
Código
Copiar el marcado
Una etiqueta y un campo no necesitan ninguna clase. .luz-field añade una pista y un error:
<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--requiredpara el asterisco rojo.- Error:
.luz-input--error,aria-invalid="true"y un.luz-field__errordespué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.listcon 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.
- Una elección de una lista: un selector o botones de radio.
- Una contraseña: su campo oculta lo que se escribe. Varias líneas: un área de texto.
Qué hacer y qué no
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.
Código
Copiar el marcado
Un campo de texto con type="email"; autocomplete="email" deja que el navegador lo rellene.
<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
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.
Código
Copiar el marcado
Un campo de texto con type="password". Usa autocomplete para decir qué es el campo:
<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
autocompleteel valorcurrent-passwordonew-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"yautocomplete="one-time-code". - Algo que el lector debe ver para comprobarlo, como una dirección: un campo de texto.
Qué hacer y qué no
current-password para iniciar sesión, new-password para registrarse.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.
Búsqueda
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.
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:
<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».listcon 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
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.
Código
Copiar el marcado
Un campo de texto con type="tel"; autocomplete="tel" deja que el navegador lo rellene:
<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
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.
Código
Copiar el marcado
Un campo de texto con type="url"; autocomplete="url" deja que el navegador lo rellene:
<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.listcon 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
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.
Código
Copiar el marcado
Un campo de texto con type="number"; min, max y step fijan lo que es válido:
<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,maxysteppara 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
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.
Código
Copiar el marcado
Un campo de texto con type="date"; min y max limitan los días:
<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
minymaxpara 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
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.
Código
Copiar el marcado
Un campo de texto con type="time":
<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
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.
Código
Copiar el marcado
Un campo de texto con type="datetime-local"; di la zona horaria en la pista:
<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, comoyyyy-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
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.
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:
<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, comoyyyy-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
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.
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:
<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, comoyyyy-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
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.
<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
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.
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:
<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.pdfoimage/*.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
acceptpara 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
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:
<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>
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,maxystepsegú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
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.
Código
Copiar el marcado
Un <textarea> nativo. .luz-input--textarea le da su altura, y maxlength su límite:
<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
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.
| Parte | Color sobre el fondo | Claro | Oscuro | Alto contraste | Mí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.
- Color
--luz-brand-primary,--luz-color-danger,--luz-focus-ring,--luz-input-bg,--luz-input-border,--luz-surface-hover,--luz-surface-strong,--luz-text-disabled,--luz-text-muted,--luz-text-primary,--luz-text-secondary- 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.