Un vistazo al proceso y las herramientas que se usan para crear la experiencia de Designcember al estilo de un calendario de festividades.
En el espíritu de diciembre y los muchos calendarios que las personas usan para hacer la cuenta regresiva y celebrar, queríamos destacar el contenido web de la comunidad y el equipo de Chrome. Todos los días, destacamos un contenido relacionado con el desarrollo y el diseño de la IU, por lo que, en total, compartimos 31 publicaciones destacadas, entre las que se encontraban 26 sitios de demostración, herramientas, anuncios, podcasts, videos, artículos y casos de éxito nuevos.
Consulta la experiencia completa en designcember.com.
Descripción general
Nuestro objetivo era ofrecer una experiencia web accesible, caprichosa, moderna y responsiva en la menor cantidad de bytes posible. Queríamos destacar nuevas APIs responsivas, como las consultas de contenedor, y mostrar un hermoso ejemplo de un modo oscuro en un sitio web centrado en el diseño y con muchos recursos. Para lograrlo, comprimimos archivos, ofrecimos varios formatos, usamos herramientas de compilación optimizadas para la generación de sitios estáticos, enviamos un nuevo polyfill y mucho más.
Comienza con la fantasía
La idea del sitio del calendario de Designcember era que funcionara como una muestra de todo el trabajo que queríamos destacar durante el mes de diciembre y, al mismo tiempo, actuara como un sitio de demostración. Decidimos construir un edificio de departamentos responsivo que pudiera ser más alto y estrecho, o más bajo y ancho, con ventanas que se reorganizaran dentro del marco. Cada ventana representaba un día (y, por lo tanto, un elemento de contenido). Trabajamos con la ilustradora Alice Lee para dar vida a nuestra visión.
Alice fue inspiradora y compartió procesos y bocetos que eran emocionantes incluso en sus primeros conceptos. Mientras ella trabajaba en el arte, nosotros hackeamos la arquitectura. Las primeras discusiones se centraron en el diseño macro, el edificio y sus ventanas. ¿Cómo se adaptarían las ventanas a una, dos o tres columnas a medida que haya más espacio de viewport disponible? ¿Hasta dónde se pueden contraer o estirar? ¿Cuál sería el tamaño máximo del edificio? ¿Cuánto se desplazarían las ventanas?
Esta es una vista previa de un prototipo responsivo con grid-auto-flow: dense
que muestra cómo el algoritmo de la cuadrícula podría colocar automáticamente las ventanas. Rápidamente nos dimos cuenta de que, si bien las cuadrículas de relación de aspecto funcionaban de forma excelente para mostrar el arte, no brindaban la oportunidad de permitir que las ventanas crecieran y se achicaran en un espacio disponible no uniforme y mostraran el poder de las consultas de contenedores.
Una vez que la cuadrícula general era relativamente estable y comunicaba un sentido de dirección con respecto a la capacidad de respuesta del edificio y sus ventanas, podíamos concentrarnos en una sola ventana. Algunas ventanas se estiraron, se encogieron, se comprimieron, se agrandaron y se volvieron a componer más que otras en la cuadrícula.
Cada ventana debería controlar una cierta cantidad de turbulencias de cambio de tamaño. A continuación, se muestra un prototipo de una ventana que demuestra su capacidad de respuesta a la turbulencia y muestra cuánto podríamos esperar que se ajuste cada ventana interactiva.
Animación de ventana con spritesheets
Algunas ventanas tienen animaciones para agregar interacción adicional a la experiencia. Las animaciones están dibujadas a mano, fotograma a fotograma, en Photoshop. Cada fotograma se exporta, se convierte en una hoja de sprites con este generador de hojas de sprites y, luego, se optimiza con Squoosh. Luego, la animación de CSS usa background-position-x
y animation-timing-function
, como se muestra en el siguiente ejemplo.
.una
background: url("/day1/una_sprite.webp") 0% 0%;
background-size: 400% auto;
}
.day:is(:hover, :focus-within) .una {
animation: una-wave .5s steps(1) alternate infinite;
}
@keyframes una-wave {
0% { background-position-x: 0%; }
25% { background-position-x: 300%; }
50% { background-position-x: 200%; }
75% { background-position-x: 100%; }
}
Algunas animaciones, como la alcancía del sexto día, fueron animaciones de CSS basadas en pasos.
Logramos este efecto con una técnica similar, usando steps()
, con la diferencia de que los fotogramas clave eran posiciones de transformación de CSS en lugar de posiciones de fondo.
Enmascaramiento de CSS
Algunas ventanas tenían formas únicas. Usamos máscaras y aspect-ratio
para crear una ventana escalable, adaptable y de forma única.
Para crear una máscara como esta para la ventana ocho, se necesitaban algunas habilidades clásicas de Photoshop, además de un poco de conocimiento sobre cómo funcionan las máscaras en la Web. Veamos la ventana para el día ocho.
Para convertirse en una máscara, la forma interna tipo trébol de cuatro hojas debe aislarse como su propia forma y rellenarse de color blanco. El blanco le indica al CSS qué contenido permanecerá y qué no. En Photoshop, se seleccionó el interior de la ventana, se difuminó 1 px (para quitar los problemas de alias) y, luego, se llenó de blanco y se exportó con la misma altura y el mismo ancho que el marco de la ventana. De esta manera, el marco y la máscara podrían superponerse directamente unos con otros para mostrar el contenido interno dentro del encuadre como se espera.
Una vez completado, el contenido de la ventana se puede modificar y siempre se mostrará dentro del marco personalizado. En la siguiente imagen, se muestra la versión del modo oscuro de la ventana, con un gradiente de fondo diferente y un filtro CSS de brillo aplicado a la luz.
El enmascaramiento también admite ventanas responsivas basadas en consultas de contenedores. En la ventana nueve, hay un personaje que está oculto detrás de una máscara hasta que la ventana tiene un tamaño más estrecho. Para asegurarse de que el usuario no pueda ajustar la imagen fuera del marco, Alice completó el personaje por completo. El personaje está enmascarado dentro de la ventana, pero las plantas no, así que otro desafío que abordamos fue superponer elementos enmascarados con capas desenmascaradas y asegurarnos de que todos escalen bien juntos.
En la siguiente imagen, se muestra cómo se ve sin la máscara en la ventana y el personaje.
Aplasta el arte
Para mantener la fidelidad de la ilustración y asegurarse de que las pantallas de alta definición no tuvieran una experiencia del usuario borrosa, Alicia trabajó con una proporción de píxeles de 3x. El plan era usar imgix y entregar imágenes y formatos optimizados en su servidor, pero descubrimos que los ajustes manuales con la herramienta Squoosh podrían ahorrarnos un 50% o más.
La ilustración tiene desafíos únicos para la compresión, en especial el trazo del pincel y el estilo de borde áspero transparente que usó Alice. Decidimos reducir cada imagen PNG exportada de Photoshop 3 veces a un PNG, un webp y un avif más pequeños. Cada tipo de archivo tiene sus propias capacidades de compresión especiales, y se necesitó comprimir más de 50 imágenes para encontrar algunos parámetros de configuración de optimización comunes.
La CLI de Squoosh se volvió crucial, ya que se optimizaron más de 200 imágenes. Hacer todo esto de forma manual habría llevado días. Una vez que tuvimos la configuración de optimización común, la proporcionamos como instrucciones de línea de comandos y procesamos por lotes carpetas completas de imágenes PNG en sus contrapartes comprimidas de WebP y AVIF.
Este es un ejemplo de un comando squoosh de la CLI de AVIF que se usó:
npx @squoosh/cli --quant '{"enabled":true,"zx":0,"maxNumColors":256,"dither":1}' --avif '{"cqLevel":19,"cqAlphaLevel":17,"subsample":1,"tileColsLog2":0,"tileRowsLog2":0,"speed":6,"chromaDeltaQ":false,"sharpness":5,"denoiseLevel":0,"tune":0}' image-1.png image-2.png image-3.png
Con el material gráfico optimizado verificado en el repositorio, podríamos comenzar a cargarlo desde HTML:
<picture>
<source srcset="/day1/inner-frame.avif" type="image/avif">
<source srcset="/day1/inner-frame.webp" type="image/webp">
<img alt="" decoding="async" role="presentation" src="/day1/inner-frame.png">
</picture>
Escribir el código fuente de la imagen era repetitivo, por lo que creamos un componente Astro para incorporar imágenes con una línea de código.
<Pic filename="day1/inner-frame" role="presentation" />
Usuarios de lectores de pantalla y teclado
Gran parte de la experiencia de Designcember se realiza a través de las ventanas interactivas y de arte. Para nosotros, era importante que un usuario de teclado pudiera usar el sitio y ver las ventanas, y que los usuarios de lectores de pantalla tuvieran una experiencia narrada agradable.
Por ejemplo, cuando incorporamos las imágenes, usamos role="presentation"
para marcar la imagen como de presentación para los lectores de pantalla. Consideramos que una experiencia del usuario de entre 5 y 12 descripciones alt
fragmentadas sería una experiencia deficiente. Por lo tanto, marcamos las imágenes como de presentación y proporcionamos una narración general de la ventana. Desplazarse por las ventanas en un lector de pantalla tiene una sensación narrativa agradable, que esperamos que ayude a transmitir la extravagancia y la diversión que el sitio quiere compartir.
En el siguiente video, se muestra una demostración de la experiencia del teclado. Las teclas Tab, Intro, barra espaciadora y Escape se usan para organizar el enfoque hacia y desde las ventanas emergentes y las ventanas.
La experiencia del lector de pantalla tiene atributos ARIA especiales que le dan claridad al contenido. Por ejemplo, los vínculos de los días solo dicen "uno" o "dos", pero con algunos elementos ARIA agregados, se anuncian como "Día uno" y "Día dos". Además, todas las imágenes se resumen en una sola etiqueta para que cada ventana tenga una descripción.
Astro, generador de sitios basado en componentes y estático en primer lugar
Astro le permitió al equipo trabajar en conjunto en el sitio con facilidad. El modelo de componentes era conocido por los desarrolladores de Angular y React, mientras que el sistema de estilo de nombres de clase con alcance ayudaba a cada desarrollador a saber que su trabajo en una ventana no iba a entrar en conflicto con nadie más.
Días como componentes
Cada día había un componente que recuperaba el estado de un almacén de datos de tiempo de compilación. Esto nos permitió ejecutar la lógica de la plantilla antes de que el HTML llegara al navegador. La lógica determinaría si el día debe mostrar la información sobre la herramienta o no, ya que los días inactivos no tienen ventanas emergentes.
Las compilaciones se ejecutan cada hora y el almacén de datos de hora de compilación desbloquea un nuevo día cuando el servidor de compilación finaliza la medianoche. Estos pequeños sistemas autoactualizables y autosuficientes mantienen el sitio actualizado.
Estilos centrados y elementos Open
Estilos de alcance de Astro escritos dentro de su modelo de componentes, lo que facilitó la distribución de la carga de trabajo entre muchos miembros del equipo y también hizo que usar Open Props fuera divertido. Los estilos de Open Props normalize.css resultaron útiles para el tema adaptable (claro y oscuro), además de ayudar a derivar el contenido, como párrafos y encabezados.
Como usuarios pioneros de Astro, nos encontramos con algunos problemas con PostCSS. Por ejemplo, no pudimos actualizar a la versión más reciente de Astro debido a demasiados problemas de compilación. Se podría dedicar más tiempo a optimizar los flujos de trabajo de compilación y desarrollo.
Contenedores flexibles
Algunas ventanas aumentan y disminuyen de tamaño, manteniendo la relación de aspecto para preservar su diseño. Usamos algunas otras ventanas para mostrar el poder de la arquitectura basada en componentes con consultas de contenedores. Las consultas de contenedor significaban que las ventanas podían tener su propia información de diseño responsivo individual y reajustarse en función de sus propios tamaños. Algunas ventanas pasaron de ser estrechas a ser anchas y fue necesario ajustar el tamaño del contenido multimedia que contenían, así como su ubicación.
A medida que haya más espacio disponible para una ventana, podríamos adaptar el tamaño o los elementos secundarios de la ventana para que se ajusten. Resultó que, para cumplir con las ventanas adaptables, las consultas de contenedores no solo serían divertidas de mostrar, sino que serían obligatorias y simplificarían de forma drástica la orquestación de ciertos diseños.
.day {
container: inline-size;
}
.day > .pane {
min-block-size: 250px;
@container (min-width: 220px) {
min-block-size: 300px;
}
@container (min-width: 260px) {
min-block-size: 310px;
}
@container (min-width: 360px) {
min-block-size: 450px;
}
}
Este enfoque es diferente de mantener una relación de aspecto. Ofrece más control y más oportunidades. A partir de cierto tamaño, muchos niños se mueven para adaptarse a un nuevo diseño.
Las consultas de contenedor también nos permitieron admitir la contención en dirección de bloque (vertical), de modo que, a medida que una ventana aumentaba de longitud, podíamos ajustar sus estilos para que se ajustaran de forma adecuada. Esto se ve en las consultas basadas en la altura, que usamos de forma independiente, y además de las consultas basadas en el ancho:
.person {
place-self: flex-end;
margin-block: 25% 50%;
margin-inline-start: -15%;
z-index: var(--layer-1);
@container (max-height: 350px) and (max-width: 425px) {
place-self: center flex-end;
inline-size: 50%;
inset-block-end: -15%;
margin-block-start: -2%;
margin-block-end: -25%;
z-index: var(--layer-2);
}
}
También usamos consultas de contenedor para mostrar y ocultar detalles a medida que el material gráfico se volvía cada vez más cargado en tamaños más pequeños y más vacío en tamaños más grandes. La ventana nueve es un excelente ejemplo de dónde entró en juego esto:
Compatibilidad con varios navegadores
Para crear una gran experiencia moderna multinavegador, especialmente para las APIs experimentales, como las consultas de contenedores, necesitamos un polyfill excelente. Enviamos una llamada a nuestro equipo y Surma dirigió una compilación para un nuevo polyfill de consulta de contenedores. El polyfill depende de ResizeObserver, MutationObserver y la función :is() de CSS. Por lo tanto, todos los navegadores modernos admiten el polyfill, específicamente Chrome y Edge a partir de la versión 88, Firefox a partir de la versión 78 y Safari a partir de la versión 14. El uso del polyfill permite cualquiera de las siguientes sintaxis:
/* These are all equivalent */
@container (min-width: 200px) {
/* ... */
}
@container (width >= 200px) {
/* ... */
}
@container size(width >= 200px) {
/* ... */
}
Modo oscuro
Un último toque esencial para el sitio web de Designcember fue un hermoso tema oscuro. Queríamos mostrar cómo puedes usar el arte para participar activamente en la creación de una gran experiencia de modo oscuro. Para ello, ajustamos los estilos de fondo de cada ventana de forma programática y usamos tanto CSS como fue necesario cuando creamos el material gráfico de la ventana. La mayoría de los fondos eran gradientes de CSS para que fuera más fácil ajustar sus valores de color. Luego, colocamos el arte sobre ellos.
Otros huevos de Pascua
Toques personales
Agregamos algunos toques personales a la página para darle más personalidad al sitio. El primero fue el elenco de personajes, inspirado en nuestro equipo. También incluimos un cursor de estilo retro en los días inactivos y jugamos con el estilo del favicon.
Toques funcionales
Uno de los toques funcionales adicionales es la función "Ir a Hoy", con un pájaro que se sienta en la parte superior del edificio. Si haces clic en el pájaro o presionas Intro, la página se desplazará hasta el día actual del mes para que puedas acceder rápidamente a los lanzamientos más recientes.
Designcember.com también tiene una hoja de estilo de impresión especial en la que, básicamente, se entrega una imagen específica que funciona mejor en papel de 8.5" x 11" para que puedas imprimir el calendario y mantener la festividad durante todo el año.
En total, se dedicó mucho trabajo a crear una experiencia web moderna, divertida y caprichosa para celebrar el desarrollo de la IU durante todo el mes de diciembre. Esperamos que lo hayas disfrutado.