Core · Campos de formulario
Elección
Elegir entre opciones que el lector ve: casilla de verificación, botón de opción, interruptor y selector.
Un selector va dentro de .luz-field, igual que en Campos de entrada.
Casilla de verificación
Una casilla que el lector marca para responder sí o no, o para elegir cualquiera de varias opciones independientes.
Código
Copiar el marcado
Una casilla nativa dentro de .luz-check-item, con su etiqueta al lado; .luz-check-group apila varias:
<div class="luz-check-group" role="group" aria-labelledby="notify-label">
<div class="luz-check-item"><input type="checkbox" id="notify-email" checked><label for="notify-email">Email</label></div>
<div class="luz-check-item"><input type="checkbox" id="notify-push"><label for="notify-push">Push</label></div>
</div>
Variantes y opciones
checked: una casilla rellena con una marca de verificación.disabled: atenuada, Tab la salta y no se envía.required: el navegador detiene el formulario hasta que se marque.
Cómo funciona
Un <input> nativo con appearance: none, redibujado por components/form.css. La etiqueta se une a él con for e id, así que un clic en el texto marca la casilla.
Sin JavaScript
Cada casilla se marca, se desmarca y se envía con su formulario.
Teclado y ARIA
- Tab pasa de una casilla a otra; Espacio marca o desmarca la que tiene el foco.
- Da a un grupo de casillas un nombre que un lector de pantalla lea antes de la primera, como hace la etiqueta en el marcado anterior.
El contraste y el foco están en la pestaña Diseño.
Diseño
Cuándo usarlo
Usa una casilla cuando el lector pueda elegir ninguna, una o varias opciones.
- Un sí o un no que se guarda con un botón: «Envíame un correo sobre las novedades».
- Una lista en la que pueden valer tantas opciones como se quiera.
Cuándo no usarlo
No uses una casilla para elegir una opción entre varias ni para un ajuste que se aplica al instante.
- Una opción entre varias: botones de opción.
- Un ajuste que surte efecto en cuanto cambia: un interruptor.
Qué hacer y qué no
Cómo escribir el contenido
- Escribe la etiqueta de modo que marcada signifique sí: «Envíame un correo sobre las novedades».
- Una línea, con mayúscula solo al inicio y sin punto final.
- Sin negaciones: «No me envíes correos» obliga al lector a desmarcar para decir que sí.
Contraste y foco
Compartido con los demás controles de elección: contraste y foco de la elección.
Tokens que usa
Compartido con los demás controles de elección: tokens de la elección.
El teclado y ARIA están en la pestaña Código.
Botón de opción
Botones redondos para elegir una opción entre unas pocas, con todas las opciones a la vista.
Código
Copiar el marcado
Los botones de opción con el mismo name forman una sola elección. Un <fieldset> con un <legend> plantea la pregunta:
<fieldset class="luz-fieldset">
<legend>Plan</legend>
<div class="luz-check-group">
<div class="luz-check-item"><input type="radio" name="plan" id="plan-free" checked><label for="plan-free">Free</label></div>
<div class="luz-check-item"><input type="radio" name="plan" id="plan-team"><label for="plan-team">Team</label></div>
</div>
</fieldset>
Variantes y opciones
checked: la opción elegida al principio. Solo una opción de un grupo puede estarlo.requireden un botón de opción: el navegador detiene el formulario hasta que el grupo tenga respuesta.disabled: Tab lo salta y no se envía.
Cómo funciona
Un <input type="radio"> nativo con appearance: none, redibujado por components/form.css: un anillo que se rellena con un punto del color de marca. El navegador forma el grupo con los botones de opción que comparten un name.
Sin JavaScript
Cada grupo funciona y envía su valor elegido con el formulario.
Teclado y ARIA
- Tab entra en el grupo, hasta la opción elegida o la primera, y sale de él. Las teclas de flecha cambian la elección dentro del grupo. Espacio elige la opción que tiene el foco.
- La leyenda da nombre al grupo y cada etiqueta da nombre a su opción.
El contraste y el foco están en la pestaña Diseño.
Diseño
Cuándo usarlo
Usa botones de opción cuando el lector elige exactamente una entre unas pocas opciones y conviene que las vea todas.
- Seis opciones o menos: un plan, una talla, un método de entrega.
- Marca desde el principio la opción que quiere la mayoría, o ninguna cuando la elección deba ser consciente.
Cuándo no usarlo
No uses botones de opción para una lista larga ni para respuestas que no son excluyentes.
- Más de seis opciones: un selector.
- Cualquier número de opciones: casillas. Un único sí o no: una casilla o un interruptor.
Qué hacer y qué no
Cómo escribir el contenido
- La leyenda es la pregunta o un sustantivo: «Plan», «Método de entrega».
- Las opciones son cortas y paralelas, con mayúscula solo al inicio y en un orden que el lector pueda prever.
- Di qué significa cada opción en su etiqueta, no en una pista al lado.
Contraste y foco
Compartido con los demás controles de elección: contraste y foco de la elección.
Tokens que usa
Compartido con los demás controles de elección: tokens de la elección.
El teclado y ARIA están en la pestaña Código.
Interruptor
Un interruptor para un ajuste que está activado o desactivado y surte efecto al instante.
Código
Copiar el marcado
Una casilla con role="switch" dentro de un <label>; el riel y el pulgar se dibujan después:
<label class="luz-toggle">
<input class="luz-toggle__input" type="checkbox" role="switch">
<span class="luz-toggle__track" aria-hidden="true"><span class="luz-toggle__thumb"></span></span>
<span class="luz-toggle__label">Weekly digest</span>
</label>
Variantes y opciones
checked: activado. El riel se rellena con el color de marca y el pulgar se desplaza al final.disabled: un riel atenuado; Tab lo salta y no se envía.
Cómo funciona
Una casilla nativa, oculta pero con foco, con role="switch". .luz-toggle dibuja el riel y el pulgar; el pulgar se mueve en sentido contrario en texto de derecha a izquierda, y los colores forzados redibujan ambos con los colores del sistema. LUZ no incluye ningún script: un cambio surte efecto cuando tu propio script actúa sobre él.
Sin JavaScript
El interruptor se activa y se desactiva, y se envía con su formulario. Aplicar el cambio al instante es tarea de tu script.
Teclado y ARIA
- Tab lleva el foco al interruptor; Espacio lo activa o lo desactiva.
- La etiqueta es el nombre;
role="switch"indica al navegador que está activado o desactivado, no marcado.
El contraste y el foco están en la pestaña Diseño.
Diseño
Cuándo usarlo
Usa un interruptor para un ajuste que se aplica en cuanto cambia, sin botón de confirmación.
- Una preferencia, un modo o una función que está activada o desactivada.
- Nombra el ajuste en la etiqueta, de modo que activado signifique que está en marcha.
Cuándo no usarlo
No uses un interruptor para una elección que espera a un botón.
- En un formulario que se envía con un botón: una casilla.
- Una opción entre varias: botones de opción.
Qué hacer y qué no
Cómo escribir el contenido
- Nombra el ajuste: «Perfil público», «Resumen semanal».
- No escribas «Activado» ni «Desactivado» en la etiqueta: el interruptor ya lo muestra.
- Sin negaciones: «Ocultar mi perfil» hace que activado signifique desactivado.
Contraste y foco
Compartido con los demás controles de elección: contraste y foco de la elección.
Tokens que usa
Compartido con los demás controles de elección: tokens de la elección.
El teclado y ARIA están en la pestaña Código.
Selector
Una lista desplegable nativa para elegir una opción entre muchas, con la caja cerrada estilizada mediante tokens.
Código
Copiar el marcado
Un select sin clase no necesita ninguna. .luz-select añade la lista abierta estilizada, donde el navegador puede dibujarla:
<div class="luz-field">
<label class="luz-field__label" for="country">Country</label>
<select class="luz-select" id="country" name="country">
<option value="">Select a country</option>
<option value="de">Germany</option>
<option value="es">Spain</option>
</select>
</div>
Variantes y opciones
aria-invalid="true": un borde de peligro más grueso; acompáñalo del texto del error.disabled: texto desactivado y un borde discontinuo.multiple,size: una lista que permanece abierta, con borde completo y sin flecha.<optgroup label>: un conjunto de opciones con nombre.
Cómo funciona
Un <select> nativo estilizado por components/select.css en dos capas: la caja cerrada en todos los navegadores y la lista abierta dentro de @supports (appearance: base-select). La flecha sigue el color del texto y pasa a la izquierda en texto de derecha a izquierda.
Sin JavaScript
No cambia nada: el selector es un elemento nativo y LUZ no le añade ningún script.
Teclado y ARIA
- Tab lleva al selector. Enter o Espacio abre la lista, Escape la cierra y las flechas arriba y abajo recorren las opciones.
- Dale un
<label for>visible y ningún rol. Para un error, ponaria-invalid="true"y haz quearia-describedbyapunte al texto.
El contraste y el foco están en la pestaña Diseño.
Diseño
Cuándo usarlo
Usa un selector cuando el lector deba elegir una opción de una lista larga cuya respuesta ya conoce.
- Un país, un año, una zona horaria: más de seis opciones y una sola respuesta.
- Las opciones son cortas y el lector puede recorrerlas en orden.
Cuándo no usarlo
Un selector oculta las opciones hasta que el lector lo abre, y a algunas personas les resulta difícil. La regla de las seis opciones es propia de LUZ.
- Seis opciones o menos: botones de opción, para que todas queden a la vista.
- Varias respuestas: casillas. No construyas nunca tu propio cuadro de lista con elementos
<div>.
Qué hacer y qué no
Cómo escribir el contenido
- La etiqueta dice qué elegir, con un sustantivo: «País», no «Seleccione por favor».
- La primera opción es una indicación con valor vacío, para que un campo obligatorio no quede respondido por defecto.
- Con mayúscula solo al inicio y en un orden que el lector pueda prever, como el alfabético.
Contraste y foco
Compartido con los demás controles de elección: contraste y foco de la elección.
Tokens que usa
Compartido con los demás controles de elección: tokens de la elección.
El teclado y ARIA están en la pestaña Código.
Contraste y foco de la elección
La etiqueta es texto principal de la página; la casilla debe distinguirse sobre ella.
| Parte | Color sobre el fondo | Claro | Oscuro | Alto contraste | Mínimo |
|---|---|---|---|---|---|
Etiqueta | --luz-text-primary sobre --luz-surface-page | 15,8:1 | 15,1:1 | 21,0:1 | 4,5:1 |
Borde de la casilla y riel del interruptor, desactivado | --luz-outline sobre --luz-surface-page | 4,3:1 | 3,6:1 | 21,0:1 | 3:1 |
Casilla marcada y riel del interruptor, activado | --luz-brand-fill sobre --luz-surface-page | 5,6:1 | 3,5:1 | 14,1:1 | 3:1 |
Marca de verificación y pulgar del interruptor, activado | --luz-text-on-fill sobre --luz-brand-fill | 6,0:1 | 4,9:1 | 14,1:1 | 3:1 |
Pulgar del interruptor, desactivado | --luz-text-on-fill sobre --luz-outline | 4,6:1 | 4,8:1 | 21,0:1 | 3:1 |
Botón de opción elegido, anillo y punto | --luz-brand-primary sobre --luz-surface-page | 5,6:1 | 7,7:1 | 14,1:1 | 3:1 |
Texto y flecha del selector | --luz-text-primary sobre --luz-input-bg | 16,5:1 | 14,0:1 | 21,0:1 | 4,5:1 |
Borde del selector | --luz-input-border sobre --luz-surface-page | 3,7:1 | 4,2:1 | 21,0:1 | 3:1 |
Borde de error del selector | --luz-color-danger sobre --luz-input-bg | 5,5:1 | 10,8:1 | 9,3:1 | 3:1 |
Texto de la lista abierta | --luz-text-primary sobre --luz-surface | 16,5:1 | 14,0:1 | 21,0:1 | 4,5:1 |
Opción bajo el puntero | --luz-text-primary sobre --luz-surface-muted | 15,8:1 | 15,1:1 | 20,1:1 | 4,5:1 |
Anillo de foco | --luz-focus-ring sobre --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 de la casilla, del riel del interruptor o del selector. - No depende solo del color: una casilla marcada está rellena y tiene una marca de verificación, un botón de opción elegido tiene un punto y el pulgar del interruptor se desplaza.
- Objetivo táctil: toda la fila, casilla y etiqueta, recibe el clic.
Tokens de la elección
Los 27 tokens que leen las reglas de estos controles, por familia de tokens. Cada familia enlaza a su página, con los valores de todos los modos.
- Color
--luz-brand-fill,--luz-brand-primary,--luz-color-danger,--luz-focus-ring,--luz-input-bg,--luz-input-border,--luz-outline,--luz-surface,--luz-surface-muted,--luz-text-disabled,--luz-text-on-fill,--luz-text-primary- Espaciado y tamaños
--luz-control-lg,--luz-control-md,--luz-space-2xs,--luz-space-3xs,--luz-space-sm,--luz-space-xl,--luz-space-xs- Tipografía
--luz-font-sans,--luz-text-control,--luz-text-md- Radio
--luz-radius-full,--luz-radius-md,--luz-radius-sm- Sombras
--luz-shadow-md- Movimiento
--luz-duration-fast
Problemas conocidos
La lista abierta de un selector se ve distinta en cada navegador y sistema. Es lo previsto.
- La caja cerrada es igual en todas partes; la lista que se abre desde ella la dibuja el navegador o el sistema operativo.
- Donde se admite
appearance: base-select(Chrome y Edge 135 y posteriores, Safari 27 y posteriores), la lista toma los colores, la forma y el espaciado de LUZ. Firefox muestra los suyos. - En los teléfonos se abre el selector del propio sistema, y LUZ no puede darle estilo.