1. Antes de comenzar

Actualmente, los usuarios indican muchas preferencias en sus dispositivos. Quieren que el sistema operativo y las apps se vean y se sientan como suyos. Las interfaces adaptadas al usuario son aquellas que están listas para usar estas preferencias y mejorar la experiencia del usuario, para que se sienta más cómodo, para que sienta que es suya. Si se hace correctamente, es posible que el usuario nunca sepa que la experiencia del usuario se está adaptando o se adaptó.
Preferencias del usuario
La elección del hardware del dispositivo es una preferencia, el sistema operativo es una elección, los colores de las apps y los sistemas operativos son preferencias, y los idiomas de los documentos de las apps y los sistemas operativos son preferencias. La cantidad de preferencias de un usuario parece aumentar cada vez más. Una página web no puede acceder a todo y por una buena razón.
Estos son algunos ejemplos de preferencias del usuario que pueden usar los CSS:
- Tamaño de la ventana gráfica del dispositivo
- Orientación del dispositivo (vertical | horizontal)
- Tamaño de fuente
- En línea o sin conexión
- Calidad de la red
- Esquema de color (claro | oscuro)
- Animaciones de la interfaz (activadas | reducidas)
- Calidad de entrada (mouse | táctil | lápiz)
- Dirección del documento y modo de escritura (de izquierda a derecha, de arriba a abajo y mucho más)
- Modo de visualización (pantalla completa | independiente | IU mínima | navegador)
Estos son algunos ejemplos de preferencias del usuario que pronto estarán disponibles en CSS:
- Datos reducidos o modo lite
- Rango de color
- Contraste (menos | más | reducir)
- Colores (fuerza los colores del usuario en la página)
- Transparencia (activada | reducida)
Consultas de medios
CSS y la Web permiten la adaptación y la capacidad de respuesta a través de consultas de medios, una condición declarativa que contiene un conjunto de estilos si esa condición es verdadera. La más común es una condición sobre el tamaño del viewport del dispositivo: si el tamaño es inferior a 800 píxeles, aquí tienes algunos mejores estilos para ese caso.
Adaptativo para el usuario
Una interfaz no adaptable es aquella que no cambia nada cuando un usuario la visita, ya que ofrece una sola experiencia a todos sin capacidad de ajuste. Una interfaz adaptable al usuario podría tener cinco apariencias y estilos diferentes para cinco usuarios diferentes. La funcionalidad es la misma, pero la estética se percibe mejor y la usabilidad de la interfaz es más sencilla para los usuarios que pueden ajustar la IU.
Requisitos previos
- Conocimientos de HTML y CSS
- Conocimiento de las herramientas para desarrolladores, como las Herramientas para desarrolladores de Google Chrome
Qué compilarás
En este codelab, compilarás un formulario adaptable al usuario que se adapte a lo siguiente:
- La preferencia del esquema de color del sistema, ya que ofrece un esquema de color claro y oscuro para los controles del formulario y los elementos de la IU circundantes
- Las preferencias de movimiento del sistema, ya que ofrece varios tipos de animaciones
- Ventanas gráficas de dispositivos pequeños y grandes para ofrecer experiencias en dispositivos móviles y computadoras de escritorio
- Varios tipos de entrada, como teclado, lector de pantalla, táctil y mouse
- Cualquier idioma y modo de lectura/escritura

Qué aprenderás
En este codelab, aprenderás sobre las funciones web modernas que te ayudarán a compilar un formulario adaptable al usuario. Aprenderás a hacer lo siguiente:
- Crea temas claros y oscuros
- Crea formularios animados y accesibles
- Diseño de formularios responsivos
- Usa unidades relativas y propiedades lógicas

Este codelab se enfoca en las interfaces adaptables al usuario. Los conceptos y los bloques de código no relacionados con esos temas se abordan superficialmente y se proporcionan para que simplemente los copies y pegues.
Requisitos
- Google Chrome 89 y versiones posteriores, o tu navegador preferido

2. Prepárate
Obtén el código
Todo lo que necesitas para este proyecto se encuentra en un repositorio de GitHub. Para comenzar, deberás obtener el código y abrirlo en tu entorno de desarrollo favorito. Como alternativa, puedes bifurcar este Codepen y trabajar desde allí.
Recomendación: Usa Codepen
- Abra una nueva pestaña del navegador.
- Ve a https://codepen.io/argyleink/pen/abBMeeq.
- Si no tienes una cuenta, crea una para guardar el trabajo.
- Haz clic en Fork.
Alternativa: Trabaja de forma local
Si quieres descargar el código y trabajar de forma local, deberás tener la versión 12 o posterior de Node.js, y un editor de código configurado y listo para usar.
Usa Git
- Visita https://github.com/argyleink/Google-IO-2021-Workshop_User-Adaptive-Interfaces.
- Clona el repositorio en una carpeta.
- Observa que la rama predeterminada es
beginning.
Cómo usar archivos
- Descomprime el archivo ZIP descargado en una carpeta.
Ejecuta el proyecto
Usa el directorio del proyecto establecido en cualquiera de los pasos anteriores y, luego, haz lo siguiente:
- Ejecuta
npm installa fin de instalar las dependencias necesarias para ejecutar el servidor. - Ejecuta
npm startpara iniciar el servidor en el puerto 3000. - Abra una nueva pestaña del navegador.
- Ve a http://localhost:3000.
Acerca del código HTML
En esta lección, se abarcarán los aspectos del HTML que se utilizan para admitir la interactividad adaptable al usuario. Este taller se enfoca específicamente en CSS. Vale la pena revisar el código HTML proporcionado si es la primera vez que creas formularios o sitios web. Las opciones de elementos HTML pueden ser fundamentales cuando se trata de accesibilidad y diseño.
Cuando esté todo listo para comenzar, este será el esqueleto que transformarás en una experiencia del usuario dinámica y adaptable.

3. Interacciones adaptativas
Rama de Git: beginning
Al final de esta sección, tu formulario de configuración se adaptará a lo siguiente:
- Control de juegos y teclado
- Mouse y táctil
- Lector de pantalla o tecnología de asistencia similar
Atributos para el código HTML
El código HTML proporcionado en el código fuente es un excelente punto de partida, ya que ya se eligieron elementos semánticos para ayudar a agrupar, ordenar y etiquetar las entradas del formulario.
Los formularios suelen ser un punto de interacción clave para una empresa, por lo que es importante que se puedan adaptar a los distintos tipos de entrada que la Web puede facilitar. Por ejemplo, es probable que sea importante tener un formulario que se pueda usar en dispositivos móviles con la función táctil. En esta sección, antes del diseño y el estilo, te aseguras de la usabilidad de la entrada adaptable.
Agrupación de entradas
El elemento <fieldset> en el código HTML se usa para agrupar entradas y controles similares. En tu formulario, tienes dos grupos: uno para el volumen y otro para las notificaciones. Esto es importante para la experiencia del usuario, ya que permite omitir secciones completas.
Ordena elementos
El orden de los elementos se proporciona de forma lógica. Esto es importante para la experiencia del usuario, de modo que el orden de la experiencia visual sea el mismo o similar para las tecnologías de gamepad, teclado o lector de pantalla.
Interacción con el teclado
Los usuarios de la Web se acostumbraron a moverse por los formularios con la tecla Tab, lo que, afortunadamente, el navegador se encarga de hacer si proporcionas los elementos HTML esperados. El uso de elementos como <button>, <input>, <h2> y <label> los convierte automáticamente en destinos de teclado o lector de pantalla.

En el video anterior, se muestra cómo las flechas y la tecla Tab pueden desplazarse por la interfaz y realizar cambios. Sin embargo, el contorno azul es muy ajustado alrededor de los elementos de entrada. Agrega los siguientes estilos para que esta interacción tenga un poco de espacio.
style.css
input {
outline-offset: 5px;
}
Qué puedes probar
- Revisa los elementos HTML que se usan en
index.html. - Haz clic en la página de demostración en tu navegador.
- Presiona las teclas
tabyshift+tabpara mover el enfoque del elemento por el formulario. - Usa el teclado para cambiar los valores de los controles deslizantes y las casillas de verificación.
- Conecta un control de juegos Bluetooth y mueve el enfoque del elemento por el formulario.
Interacción con el mouse
Los usuarios de la Web se acostumbraron a interactuar con formularios con el mouse. Intenta usar el mouse en el formulario. Los controles deslizantes y las casillas de verificación funcionan, pero puedes hacerlo mejor. Esas casillas de verificación son bastante pequeñas para hacer clic con el mouse.

¿Ves cómo obtienes dos funciones de experiencia del usuario para conectar tus etiquetas y sus entradas?
La primera característica es tener opciones con las que interactuar, y la etiqueta es mucho más fácil de apuntar con un mouse que un cuadrado pequeño.
La segunda característica es saber exactamente para qué entrada es una etiqueta. Sin CSS, es bastante difícil determinar qué etiqueta corresponde a qué casilla de verificación, a menos que proporciones algunos atributos.
Esta conexión explícita también mejora la experiencia de los lectores de pantalla, que se abordan en la siguiente sección.
No asociado: No hay atributos que conecten los elementos.
<input type="checkbox">
<label>...</label>
Asociados: Atributos que conectan los elementos
<input type="checkbox" id="voice-notifications" name="voice-notifications">
<label for="voice-notifications">...</label>
El código HTML proporcionado ya atribuyó todas las entradas y etiquetas. Vale la pena investigar más si este es un concepto nuevo para ti.
Qué puedes probar
- Coloca el cursor sobre una etiqueta y observa cómo se destaca la casilla de verificación.
- Investiga un elemento de etiqueta con las herramientas para desarrolladores de Chrome para visualizar el área de la superficie en la que se puede hacer clic y que puede seleccionar la casilla de verificación.
Interacción con el lector de pantalla
La tecnología de asistencia puede interactuar con este formulario y, con algunos atributos HTML, puede hacer que la experiencia del usuario sea más fluida.

Para los usuarios que navegan por el formulario actual con un lector de pantalla en Chrome, hay una parada innecesaria en el elemento <picture> (no específico de Chrome). Es probable que un usuario con un lector de pantalla lo esté usando debido a una discapacidad visual, por lo que detenerse en una imagen no es útil. Puedes ocultar elementos de los lectores de pantalla con un atributo.
index.html
<picture aria-hidden="true">
Ahora, los lectores de pantalla omiten el elemento que era puramente visual.

El elemento de control deslizante input[type="range"] tiene un atributo ARIA especial: aria-labelledby="media-volume". Esto proporciona instrucciones especiales para que el lector de pantalla las use y mejore la experiencia del usuario.
Qué puedes probar
- Usa la tecnología de lector de pantalla de tu sistema operativo para mover el enfoque por el formulario.
- Descarga y prueba algún software de lector de pantalla en el formulario.
4. Diseños adaptables
Rama de Git: layouts
Al final de esta sección, la página de configuración tendrá las siguientes características:
- Crea un sistema de espaciado con propiedades personalizadas y unidades relativas del usuario.
- Escribe cuadrículas de CSS para lograr una alineación y un espaciado flexibles y responsivos
- Usa propiedades lógicas para diseños adaptables a nivel internacional
- Escribe consultas de medios para adaptar los diseños compactos y espaciosos.

Espacios
Una clave para un diseño agradable es una paleta limitada de opciones de espaciado. Esto ayuda a que el contenido encuentre alineaciones y armonías naturales.
Propiedades personalizadas
Este taller se basa en un conjunto de siete tamaños de propiedades personalizadas.
- Coloca estos elementos en la parte superior de
style.css:
style.css
:root {
--space-xxs: .25rem;
--space-xs: .5rem;
--space-sm: 1rem;
--space-md: 1.5rem;
--space-lg: 2rem;
--space-xl: 3rem;
--space-xxl: 6rem;
}
Los nombres se encuentran cerca de la redacción que las personas usarían entre sí para describir el espacio. También usas unidades rem exclusivamente para el tamaño legible de unidades completas que se adapta y tiene en cuenta las preferencias del usuario.
Diseños de página
A continuación, debes establecer algunos estilos de documento, quitar márgenes de los elementos y establecer la fuente en una agradable sans-serif.
- Agrega lo siguiente a
style.css:
style.css
* {
box-sizing: border-box;
margin: 0;
}
html {
block-size: 100%;
}
body {
min-block-size: 100%;
padding-block-start: var(--space-xs);
padding-block-end: var(--space-xs);
}
¡Ese es tu primer uso de las propiedades personalizadas de espaciado! Con esto, comienza tu viaje espacial.
Tipografía
La fuente de este diseño es adaptativa. La palabra clave system-ui usará la fuente de la interfaz que el sistema operativo del usuario haya decidido que es la óptima.
body {
font-family: system-ui, sans-serif;
}
h1,h2,h3 {
font-weight: 500;
}
small {
line-height: 1.5;
}
Los estilos para h1, h2 y h3 son menores y estilísticos. Sin embargo, el elemento small necesita el line-height adicional para cuando el texto se ajusta. De lo contrario, se amontonará demasiado.
Propiedades lógicas
Observa que padding en body usa propiedades lógicas (block-start, block-end) para especificar el lado. Las propiedades lógicas se usarán de forma extensiva en el resto del codelab. Al igual que una unidad de rem, también se adaptan al usuario. Este diseño se puede traducir a otro idioma y establecer en las direcciones naturales de escritura y del documento a las que el usuario está acostumbrado en su idioma nativo. Las propiedades lógicas desbloquean la compatibilidad con esto con solo una definición de espacio, dirección o alineación.

Las cuadrículas y los diseños de Flexbox ya son relativos al flujo, lo que significa que los diseños escritos para un idioma serán contextuales y se aplicarán de forma adecuada para otros. Direccionalidad adaptable: El contenido fluye en relación con la direccionalidad del documento.
Las propiedades lógicas te permiten llegar a más usuarios con menos estilos para escribir.
Diseños de cuadrícula de CSS
La propiedad grid de CSS es una potente herramienta de diseño con muchas funciones para abordar tareas complejas. Compilarás algunos diseños de cuadrícula simples y uno complejo. También trabajarás de afuera hacia adentro, desde diseños macro hasta diseños micro. Tus propiedades personalizadas de espaciado serán fundamentales, ya que no solo se usarán como valores de padding o margen, sino también como tamaños de columnas, radios de borde y mucho más.
A continuación, se muestra una captura de pantalla de las Herramientas para desarrolladores de Chrome que superponen cada diseño de cuadrícula de CSS al mismo tiempo:

- Agrega cada uno de los siguientes estilos a
style.css:
<main>
main {
display: grid;
gap: var(--space-xl);
place-content: center;
padding: var(--space-sm);
}
De forma predeterminada, la cuadrícula coloca cada elemento secundario en su propia fila, lo que la hace ideal para apilar elementos. También tiene el beneficio adicional de usar gap. Anteriormente, estableciste margin: 0 en todos los elementos con el selector *, lo que ahora es importante, ya que usas gap para el espaciado. Gap no solo es un solo lugar para administrar el espacio en un contenedor, sino que su flujo es relativo.
<form>
form {
max-width: 89vw;
display: grid;
gap: var(--space-xl) var(--space-xxl);
align-items: flex-start;
grid-template-columns:
repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
}
Este es el diseño de cuadrícula más complejo, pero representa el aspecto adaptable más interesante:
max-widthproporciona un valor para que el algoritmo de diseño lo use cuando decida qué tan grande puede ser.gapusa propiedades personalizadas y pasa unrow-gapdiferente decolumn-gap.align-itemsse establece enflex-startpara no estirar las alturas de los elementos.grid-template-columnstiene una sintaxis compleja, pero el objetivo es conciso: mantén las columnas35chanchas y nunca menores que10ch, y coloca elementos en columnas si hay espacio; de lo contrario, las filas son adecuadas.
- Prueba cambiar el tamaño del navegador. Mira cómo el formulario se contrae en filas en una ventana gráfica pequeña, pero fluye en columnas nuevas si hay espacio, adaptándose sin consultas de medios. Esta estrategia de estilos responsivos sin consultas de medios es especialmente útil para los componentes o los diseños centrados en el contenido.
<section>
section {
display: grid;
gap: var(--space-md);
}
Cada sección debe ser una cuadrícula de filas con un espacio medio entre los elementos secundarios.
<header>
header {
display: grid;
gap: var(--space-xxs);
}
Cada encabezado debe ser una cuadrícula de filas con un espacio muy pequeño entre los elementos secundarios.
<fieldset>
fieldset {
padding: 0;
display: grid;
gap: 1px;
border-radius: var(--space-sm);
overflow: hidden;
}
Este diseño es responsable de crear una apariencia similar a una tarjeta y agrupar las entradas. overflow: hidden y gap: 1px se vuelven claros cuando agregas color en la siguiente sección.
.fieldset-item
.fieldset-item {
display: grid;
grid-template-columns: var(--space-lg) 1fr;
gap: var(--space-md);
padding: var(--space-sm) var(--space-md);
}
Este diseño es responsable de centrar el ícono y la casilla de verificación con sus etiquetas y controles asociados. La primera columna de la plantilla de cuadrícula, var(--space-lg), crea una columna más ancha que el ícono, por lo que un elemento secundario tiene un lugar para centrarse.
Este diseño muestra cuántas decisiones de diseño ya se tomaron en las propiedades personalizadas. El relleno, los espacios y una columna se dimensionaron dentro de la armonía del sistema con los valores que ya definiste.
.fieldset-item <picture>
.fieldset-item > picture {
block-size: var(--space-xl);
inline-size: var(--space-xl);
clip-path: circle(50%);
display: inline-grid;
place-content: center;
}
Este diseño es responsable de la configuración, el tamaño del círculo del ícono, la creación de una forma circular y el centrado de una imagen dentro de él.
Alineación de <picture> y [casilla de verificación]
.fieldset-item > :is(picture, input[type="checkbox"]) {
place-self: center;
}
Este diseño aísla el centrado en los elementos de imagen y casilla de verificación con el :is pseudoselectores.
- Reemplaza el selector
picture > svgpor.fieldset-item svgde la siguiente manera:
.fieldset-item <svg>
.fieldset-item svg {
block-size: var(--space-md);
}
Esto establece el tamaño del ícono SVG en un valor del sistema de tamaño.
.sm-stack
.sm-stack {
display: grid;
gap: var(--space-xs);
}
Esta clase de utilidad es para los elementos de etiqueta de la casilla de verificación para espaciar el texto de ayuda de la casilla de verificación.
input[type="checkbox"]
input[type="checkbox"] {
inline-size: var(--space-sm);
block-size: var(--space-sm);
}
Estos diseños aumentan el tamaño de una casilla de verificación con valores de nuestro conjunto de espaciado.
Qué puedes probar
- Abre las Herramientas para desarrolladores de Chrome y busca insignias de cuadrícula en el código HTML del panel Elements. Haz clic en ellos para activar las herramientas de depuración.
- Abre las Herramientas para desarrolladores de Chrome y coloca el cursor sobre un espacio en el panel Estilos.
- Abre las Herramientas para desarrolladores de Chrome, ve al panel Estilos y cambia de Estilos a Diseños. Explora esta área activando y desactivando su configuración y activando los diseños.
Consultas de medios
El siguiente CSS adapta los diseños según el tamaño y la orientación del viewport con la intención de ajustar el espaciado o la disposición para que sean óptimos según el contexto del viewport.
<main>
@media (min-width: 540px) {
main {
padding: var(--space-lg);
}
}
@media (min-width: 800px) {
main {
padding: var(--space-xl);
}
}
Estas dos consultas de medios le dan a main más padding a medida que hay más espacio disponible en la ventana gráfica. Esto significa que comienza con una cantidad compacta y pequeña de relleno, pero ahora se vuelve cada vez más espacioso a medida que hay más espacio disponible.
<form>
form {
--repeat: auto-fit;
grid-template-columns:
repeat(var(--repeat), minmax(min(10ch, 100%), 35ch));
}
@media (orientation: landscape) and (min-width: 640px) {
form {
--repeat: 2;
}
}
El formulario ya respondía al tamaño de la ventana gráfica con auto-fit, pero, durante las pruebas en un dispositivo móvil, al girar el dispositivo en horizontal, los dos grupos de formularios no se colocan uno al lado del otro. Adapta el diseño a este contexto con una consulta de medios orientation y una verificación del ancho del viewport. Ahora, si el dispositivo está en posición horizontal y tiene al menos 640 píxeles de ancho, fuerza dos columnas cambiando la propiedad personalizada --repeat a un número en lugar de la palabra clave auto-fit.
.fieldset-item
@media (min-width: 540px) {
.fieldset-item {
grid-template-columns: var(--space-xxl) 1fr;
gap: var(--space-xs);
padding: var(--space-md) var(--space-xl) var(--space-md) 0;
}
}
Esta consulta de medios es otra expansión del espaciado cuando hay más espacio disponible en el viewport. La plantilla de cuadrícula expande la primera columna con una propiedad personalizada más grande (var(--space-xxl)) en la plantilla. El padding también se aplica a propiedades personalizadas más grandes.
Qué puedes probar
- Expande y contrae el navegador, y observa cómo se ajusta el espacio.
- Obtén una vista previa en un dispositivo móvil
- Vista previa en un dispositivo móvil en modo de paisaje
5. Color adaptable
Rama de Git: colors
Al final de esta sección, tu formulario de configuración tendrá las siguientes características:
- Adaptarse a las preferencias de colores claros y oscuros
- Tener un esquema de colores derivado de un código hexadecimal de la marca
- Tener colores accesibles

HSL
En la siguiente sección, crearás un sistema de color con HSL para ayudarte a crear un tema claro y oscuro. Se basa en este concepto fundamental de CSS: calc().
HSL significa tono, saturación y luminosidad. El tono es un ángulo, como un punto en un reloj, mientras que la saturación y la luminosidad son porcentajes. calc() puede realizar cálculos matemáticos con porcentajes y ángulos. Puedes realizar cálculos de luminosidad y saturación en esos porcentajes en CSS. Combina los cálculos de canales de color con propiedades personalizadas y obtendrás un esquema de colores moderno y dinámico en el que las variantes se calculan a partir de un color base, lo que te ayudará a evitar administrar una gran cantidad de colores en el código.

Propiedades personalizadas
En esta sección, compilarás un conjunto de propiedades personalizadas para usarlas en el resto de tus diseños. De manera similar al conjunto de espaciado que creaste antes en la etiqueta :root, agregarás colores.
Supongamos que el color de la marca de tu app es #0af. Tu primera tarea es convertir este valor de color hexadecimal en un valor de color HSL: hsl(200 100% 50%). Esta conversión revela los canales de color de tu marca en HSL, que puedes usar calc() para calcular varios colores complementarios de la marca.
Cada uno de los siguientes bloques de código de esta sección se debe agregar al mismo selector :root.
Canales de la marca
:root {
--hue: 200;
--saturation: 100%;
--lightness: 50%;
}
Los tres canales HSL se extrajeron y se colocaron en sus propias propiedades personalizadas.
- Usa las tres propiedades tal como están y recrea el color de la marca.
Marca
:root {
--brand: hsl(
var(--hue)
calc(var(--saturation) / 2)
var(--lightness)
);
}
Dado que tu esquema de color es oscuro de forma predeterminada, es una buena práctica desaturar los colores para usarlos en superficies oscuras (de lo contrario, pueden vibrar a la vista o ser inaccesibles). Para quitarle saturación al color de tu marca, usa el tono y la luminosidad tal como están, pero reduce la saturación a la mitad con alguna división: calc(var(--saturation) / 2). Ahora, el color de tu marca se ajusta correctamente al tema, pero está desaturado para su uso.
Texto
:root {
--text1: hsl(var(--hue) 15% 85%);
--text2: hsl(var(--hue) 15% 65%);
}
Para el texto de lectura en nuestro tema oscuro, usas el tono de la marca como base, pero creas colores casi blancos a partir de él. Muchos usuarios creerán que el texto es blanco, cuando en realidad es azul muy claro. Mantenerse dentro del mismo tono es una buena forma de crear armonía en el diseño. --text1 es 85% blanco y --text2 es 65% blanco, y ambos tienen muy poca saturación.
- Después de agregar el código a tu proyecto, abre las Herramientas para desarrolladores de Chrome y explora cómo cambiar los valores de estos canales. Siente cómo interactúan entre sí el HSL y sus canales. Tal vez prefieras más o menos saturación.
Superficie
:root {
--surface1: hsl(var(--hue) 10% 10%);
--surface2: hsl(var(--hue) 10% 15%);
--surface3: hsl(var(--hue) 5% 20%);
--surface4: hsl(var(--hue) 5% 25%);
}
El texto es muy claro porque las superficies serán oscuras en el modo oscuro. En los casos en que los colores del texto usaban valores de luminosidad altos (85% y más), las superficies usarán valores más bajos (30% y menos). Tener un rango saludable entre los rangos de luminosidad entre la superficie y el texto ayudará a garantizar colores accesibles para que los usuarios puedan leer.
- Observa cómo los colores comienzan con el gris más oscuro con un 10% de luminosidad y un 10% de saturación, y luego se desaturan a medida que se vuelven más claros. Cada superficie nueva es un 5% más ligera que la anterior. La saturación también se reduce un poco en las superficies más claras. Intenta establecer la saturación de todas las superficies en un 10%. ¿Te gusta más o menos?
Tema claro
Con un conjunto adecuado de colores de texto y superficie que especifican el tema oscuro, es hora de adaptarse a una preferencia de tema claro actualizando las propiedades personalizadas de color dentro de una consulta de medios prefers-color-scheme.
Usarás la misma técnica de mantener una gran diferencia en los valores de luminosidad entre los colores de las superficies y el texto para que los colores contrasten bien.
Marca
@media (prefers-color-scheme: light) {
:root {
--brand: hsl(
var(--hue)
var(--saturation)
var(--lightness)
);
}
}
Primero, está el color de la marca. Necesita que se restablezca la saturación a su máxima potencia.
Texto
@media (prefers-color-scheme: light) {
:root {
--text1: hsl(
var(--hue)
var(--saturation)
10%
);
--text2: hsl(
var(--hue)
calc(var(--saturation) / 2)
30%
);
}
}
De manera similar a como el tema oscuro tenía colores de texto azul muy claro, en el tema claro los colores de texto son azul muy oscuro. Ver 10% y 30% como los valores de luminosidad del color HSL debería indicarte que estos colores son oscuros.
Surface
@media (prefers-color-scheme: light) {
:root {
--surface1: hsl(var(--hue) 20% 90%);
--surface2: hsl(var(--hue) 10% 99%);
--surface3: hsl(var(--hue) 10% 96%);
--surface4: hsl(var(--hue) 10% 85%);
}
}
Estos colores de superficie son los primeros en romper patrones. Lo que hasta ahora parecía bastante razonable y lineal ahora se rompe. Lo bueno es que puedes jugar con combinaciones de colores del tema claro en HSL aquí mismo en el código y ajustar la luminosidad y la saturación para crear un esquema de colores claros agradable que no sea demasiado frío ni azul.
Cómo usar el sistema de colores
Ahora que los colores están definidos, es hora de usarlos. Tienes un color de marca de acento llamativo, dos colores de texto y cuatro colores de superficie.
- En las siguientes secciones de código, busca el selector coincidente y agrega el CSS de color al bloque de código existente.
<body>
body {
background: var(--surface1);
color: var(--text1);
}
Los colores primarios de la página son los primeros colores de superficie y texto que creaste, lo que también establece la cantidad predeterminada de contraste en su máximo. Se puede comenzar a probar la activación y desactivación de los modos claro y oscuro.
<fieldset>
fieldset {
border: 1px solid var(--surface4);
background: var(--surface4);
}
Este es el elemento similar a una tarjeta de tu diseño. El borde de 1 píxel y el espacio de 1 píxel son del mismo color y representan la superficie detrás de cada .fieldset-item. Esto crea una armonía visual agradable y es fácil de mantener.
.fieldset-item
.fieldset-item {
background: var(--surface3);
}
Cada entrada de formulario se encuentra en su propia superficie. Esperamos que veas cómo se unen estos elementos y cómo se superponen las variaciones de luminosidad.
.fieldset-item > picture
.fieldset-item > picture {
background: var(--surface4);
}
Esta es una elección de estilo para mostrar la forma circular que rodea el ícono. En la siguiente sección, se hará evidente por qué.
.fieldset-item svg
.fieldset-item svg {
fill: var(--text2);
}
Los íconos del formulario están configurados para usar el texto alternativo --text2. Los diseños en los que los íconos rellenos son ligeramente más claros que el texto evitan que se vean demasiado pesados.
.fieldset-item:focus-within svg
.fieldset-item:focus-within svg {
fill: var(--brand);
}
Este selector coincide con el elemento contenedor de entrada cuando se interactúa con una de las entradas que contiene y apunta al SVG para destacarlo con el color de acento de tu marca. Esto proporciona una buena UX de retroalimentación del formulario, en la que la interacción con las entradas destaca su iconografía pertinente.
<small>
small {
color: var(--text2);
}
Es texto pequeño. Debe ser ligeramente tenue en comparación con los encabezados y los párrafos (contenido principal).
Controles de formulario oscuros
:root {
color-scheme: dark light;
}
Este toque final agradable le indica al navegador que esta página admite temas claros y oscuros. El navegador nos recompensa con controles de formulario oscuros.
6. Animación adaptable
Rama de Git: animations
Al final de esta sección, la página de configuración tendrá las siguientes características:
- Adaptarse a las preferencias de movimiento del usuario
- Responder a la interacción del usuario

Movimiento reducido frente a sin movimiento
La preferencia del usuario que se encuentra en el sistema operativo para el movimiento no ofrece un valor de sin animación. La opción es reducir el movimiento. Las animaciones de transición gradual, las transiciones de color y mucho más siguen siendo deseables para los usuarios que prefieren un movimiento reducido.
En esta página de configuración, no hay mucho movimiento en términos de desplazamiento por la pantalla. El movimiento es más un efecto de escala, como si el elemento se acercara al usuario. Es tan trivial ajustar tu código CSS para adaptarlo al movimiento reducido que reduces las transiciones de escalamiento.
Estilos de interacción
<fieldset>
fieldset {
transition: box-shadow .3s ease;
}
fieldset:focus-within {
box-shadow: 0 5px 20px -10px hsl(0 0% 0% / 50%);
}
Cuando un usuario interactúa con las entradas de uno de los elementos con aspecto de tarjeta <fieldset>, se agrega un efecto de elevación. La interfaz empuja un elemento hacia adelante, lo que ayuda al usuario a enfocarse a medida que el grupo de formularios contextual se acerca a él.
.fieldset-item
.fieldset-item {
transition: background .2s ease;
}
.fieldset-item:focus-within {
background: var(--surface2);
}
Cuando el usuario interactúa con una entrada, el fondo de la capa del elemento específico cambia a un color de superficie destacado, otra función de la interfaz de asistencia para ayudar a atraer la atención del usuario y señalar que se está recibiendo la entrada. En la mayoría de los casos, no es necesario reducir las transiciones de color.
.fieldset-item > picture
@media (prefers-reduced-motion: no-preference) {
.fieldset-item > picture {
clip-path: circle(40%);
transition: clip-path .3s ease;
}
.fieldset-item:focus-within picture {
clip-path: circle(50%);
}
}
Esta es una animación de clip-path que solo debes usar si el usuario no tiene preferencias en cuanto a la reducción de movimiento. El primer selector y los primeros estilos restringen la ruta de recorte circular en un 10% y establecen algunos parámetros de transición. El segundo selector y estilo espera a que los usuarios interactúen con una entrada y, luego, aumenta el círculo del ícono. Un efecto sutil, pero agradable cuando está bien.
7. Felicitaciones
Rama de Git: complete
¡Felicitaciones! Creaste correctamente una interfaz adaptable al usuario.
Ahora conoces los pasos clave necesarios para crear interfaces que se adapten a diversos parámetros de configuración y situaciones del usuario.