Diseño del edificio

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.

El sitio de Designcember.

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 contenido). Trabajamos con la ilustradora Alice Lee para dar vida a nuestra visión.

Bocetos del esqueleto de la página de Designcember.

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 podrían contraerse o estirarse? ¿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 que usa grid-auto-flow: dense y muestra cómo el algoritmo de 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.

Animación que muestra cómo este esquema de página responde a diferentes tamaños de pantalla.
Consulta esta demostración en CodePen.

Una vez que la cuadrícula general fue relativamente estable y transmitió un sentido de dirección para la capacidad de respuesta del edificio y sus ventanas, pudimos enfocarnos 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.

Esquemas de página que muestran cómo se muestran las ventanas en diferentes puntos de inflexión.

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%; }
}

Animación que muestra la ventana del primer día.

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 adaptable, escalable y con 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 del octavo día.

La ventana del octavo día.

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 se pueden superponer directamente, lo que muestra el contenido interno dentro del marco como se espera.

Imagen de máscara de trébol

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.

La ventana del día ocho en modo oscuro.

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, por lo que otro desafío que enfrentamos fue superponer elementos enmascarados con capas no enmascaradas y asegurarnos de que todos se ajustaran bien.

En la siguiente imagen, se muestra cómo se ve sin la máscara en la ventana y el personaje.

La imagen de la ventana nueve sin la máscara

Aplasta el arte

Para mantener la fidelidad de la ilustración y garantizar que las pantallas de alta definición no tengan una experiencia del usuario desenfocada, Alice trabajó con una relació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.

Usa Squoosh para comprimir imágenes.

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 comprimieron más de 50 imágenes para encontrar algunos parámetros de configuración de optimización comunes.

La CLI de Squioosh se volvió fundamental con más de 200 imágenes para optimizar. Hacer todo eso de forma manual habría tardado 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 enteras 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 facilitó que el equipo trabajara en conjunto en el sitio. El modelo de componentes era familiar para los desarrolladores de Angular y React, mientras que el sistema de estilo de nombre de clase con alcance ayudó a cada desarrollador a saber que su trabajo en una ventana no entraría en conflicto con nadie más.

Días como componentes

Cada día era 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á si el día debe mostrar su información sobre herramientas 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 tiempo de compilación desbloquearía un día nuevo cuando el servidor de compilación supere 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 fueron útiles con el tema adaptable (claro y oscuro), además de ayudar a controlar el contenido, como los párrafos y los 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 otras ventanas para mostrar la potencia de la arquitectura basada en componentes con consultas de contenedores. Las consultas de contenedor significaban que las ventanas podían tener su 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.

Una demostración de cómo cambian las ventanas a medida que tienen más espacio.

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 un tamaño determinado, 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 un llamado a nuestro equipo y Surma lideró una compilación para un nuevo polyfill de consulta de contenedor. 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

Las versiones del modo claro y oscuro del sitio de Designcember, una al lado de la otra.

Un último toque que fue 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 material gráfico sobre estos.

Otros huevos de Pascua

Detalles 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.

Opciones de favicon y estilos de cursor personalizados

Detalles 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 este pájaro o presionas Intro, la página te llevará al 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 por tu cuenta y mantener la festividad durante todo el año.

Impreso del diseño del calendario en tamaño póster
Una sostiene una copia impresa grande del calendario.

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.

Partes del calendario con anotaciones y notas visuales