Conception de bâtiments

Découvrez le processus et les outils utilisés pour créer l'expérience de type calendrier de l'Avent de Designcember.

En cette période de fêtes de fin d'année, nous avons voulu mettre en avant des contenus Web de la communauté et de l'équipe Chrome. Chaque jour, nous avons mis en avant un contenu lié au développement et à la conception d'UI, soit 31 contenus au total, dont 26 nouveaux sites de démonstration, outils, annonces, podcasts, vidéos, articles et études de cas.

Découvrez l'expérience complète sur designcember.web.app.

Site Designcember.

Présentation

Notre objectif était de proposer une expérience Web accessible, fantaisiste, moderne et responsive en utilisant le moins d'octets possible. Nous voulions mettre en avant les nouvelles API responsives, comme les requêtes de conteneur, et inclure un bel exemple de mode sombre dans un site Web axé sur le design et riche en ressources. Pour ce faire, nous avons compressé les fichiers, proposé plusieurs formats, utilisé des outils de compilation optimisés pour la génération de sites statiques, fourni un nouveau polyfill, etc.

Commencer avec une touche de fantaisie

L'idée du site du calendrier Designcember était de servir de vitrine pour tous les travaux que nous souhaitions mettre en avant tout au long du mois de décembre, tout en servant lui-même de site de démonstration. Nous avons décidé de construire un immeuble réactif qui pouvait devenir plus haut et plus étroit, ou plus bas et plus large, avec des fenêtres qui se réorganisaient dans le cadre. Chaque fenêtre représentait un jour (et donc un contenu). Nous avons collaboré avec l'illustratrice Alice Lee pour concrétiser notre vision.

Croquis du squelette de la page Designcember.

Alice était une source d'inspiration. Elle partageait des processus et des croquis qui étaient passionnants, même à l'état de concepts préliminaires. Pendant qu'elle travaillait sur l'art, nous avons piraté l'architecture. Les premières discussions ont porté sur la mise en page générale, le bâtiment et ses fenêtres. Comment les fenêtres s'adapteraient-elles à une, deux ou trois colonnes à mesure que l'espace de la fenêtre d'affichage deviendrait plus important ? Dans quelle mesure peuvent-ils se rétrécir ou s'étirer ? Quelle serait la taille maximale du bâtiment ? De combien les fenêtres se déplaceraient-elles ?

Voici un aperçu d'un prototype responsif utilisant grid-auto-flow: dense, qui montre comment les fenêtres peuvent être placées automatiquement par l'algorithme de grille. Nous nous sommes vite rendu compte que, si les grilles de format étaient parfaites pour présenter des œuvres d'art, elles ne permettaient pas aux fenêtres de s'agrandir et de se réduire dans un espace disponible non uniforme, ni de montrer la puissance des requêtes de conteneur.

Animation montrant comment ce wireframe s'adapte à différentes tailles d'écran.
Découvrez cette démo sur CodePen.

Une fois la grille générale relativement stable et communiquant un sens de l'orientation pour la réactivité du bâtiment et de ses fenêtres, nous avons pu nous concentrer sur une seule fenêtre. Certaines fenêtres de la grille se sont étirées, réduites, comprimées, agrandies et recomposées plus que d'autres.

Wireframes montrant comment les fenêtres s'affichent à différents points d'arrêt.

Chaque fenêtre doit gérer une certaine quantité de turbulence de redimensionnement. Vous trouverez ci-dessous un prototype de fenêtre montrant sa réactivité aux turbulences, indiquant l'ajustement attendu pour chaque fenêtre interactive.

Animation de fenêtre avec des feuilles de sprite

Certaines fenêtres sont animées pour rendre l'expérience plus interactive. Les animations sont dessinées à la main, frame par frame, dans Photoshop. Chaque frame est exportée, transformée en feuille de sprite avec ce générateur de feuille de sprite, puis optimisée avec Squoosh. L'animation CSS utilise ensuite background-position-x et animation-timing-function, comme illustré dans l'exemple suivant.

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

Animation montrant la fenêtre pour le premier jour.

Certaines animations, comme la tirelire du sixième jour, étaient des animations CSS par étapes. Nous avons obtenu cet effet avec une technique similaire, en utilisant steps(), à la différence que les images clés étaient des positions de transformation CSS au lieu de positions d'arrière-plan.

Masquage CSS

Certaines fenêtres avaient des formes uniques. Nous avons utilisé des masques et aspect-ratio pour créer une fenêtre évolutive, de forme unique et adaptative.

Pour créer un masque, comme celui de la fenêtre 8, il a fallu faire preuve de compétences classiques en matière de Photoshop, ainsi que d'une certaine connaissance du fonctionnement des masques sur le Web. Examinons la fenêtre du huitième jour.

Période pour le huitième jour.

Pour devenir un masque, la forme intérieure en trèfle à quatre feuilles doit être isolée et remplie en blanc. La couleur blanche indique au CSS le contenu à conserver, et tout ce qui se trouve en dehors de la zone blanche sera supprimé. Dans Photoshop, l'intérieur de la fenêtre a été sélectionné, puis un contour progressif de 1 px a été appliqué (pour supprimer les problèmes d'aliasing). Ensuite, l'intérieur a été rempli en blanc et exporté avec la même hauteur et la même largeur que le cadre de la fenêtre. De cette façon, le cadre et le masque peuvent être superposés directement, ce qui permet d'afficher le contenu intérieur du cadre comme prévu.

Image de masque Clover

Une fois l'opération terminée, le contenu de la fenêtre peut être modifié et semble toujours rester dans le cadre personnalisé. L'image suivante montre la version en mode sombre de la fenêtre, avec un dégradé d'arrière-plan différent et un filtre CSS de luminosité appliqué à la lumière.

Fenêtre du huitième jour en mode sombre.

Le masquage est également compatible avec les fenêtres responsives basées sur des requêtes de conteneur. Dans la fenêtre 9, un personnage est caché derrière un masque jusqu'à ce que la fenêtre soit plus étroite. Pour s'assurer que l'utilisateur ne puisse pas ajuster l'image hors du cadre, Alice a terminé le personnage pour nous. Le personnage est masqué dans la fenêtre, mais pas les plantes. Nous avons donc dû relever un autre défi : superposer des éléments masqués avec des calques non masqués et nous assurer qu'ils s'adaptaient tous bien ensemble.

L'image suivante montre à quoi cela ressemble sans le masque sur la fenêtre et le personnage.

Image de la fenêtre 9 sans le masque.

Écraser l'art

Pour préserver la fidélité de l'illustration et s'assurer que les écrans haute définition n'offrent pas une expérience utilisateur floue, Alice a travaillé avec un ratio de pixels de 3x. Nous avions prévu d'utiliser imgix pour diffuser des images et des formats optimisés sur notre serveur, mais nous avons constaté que les ajustements manuels avec l'outil Squoosh pouvaient nous faire économiser 50 % ou plus.

Utiliser Squoosh pour compresser des images.

La compression pose des défis uniques pour les illustrations, en particulier pour le style de traits de pinceau et de bords bruts transparents utilisé par Alice. Nous avons choisi de compresser chaque image PNG exportée au format 3x Photoshop dans des formats PNG, WebP et AVIF plus petits. Chaque type de fichier possède ses propres capacités de compression. Il a fallu compresser plus de 50 images pour trouver des paramètres d'optimisation courants.

La CLI Squoosh est devenue essentielle avec plus de 200 images à optimiser. Les optimiser toutes manuellement aurait pris des jours. Une fois les paramètres d'optimisation communs définis, nous les avons fournis sous forme d'instructions de ligne de commande et avons traité par lot des dossiers entiers d'images PNG pour les convertir en leurs équivalents compressés WebP et AVIF.

Voici un exemple de commande squoosh CLI AVIF utilisée :

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

Une fois les illustrations optimisées enregistrées dans le dépôt, nous pouvons commencer à les charger à partir du code 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>

L'écriture du code source de l'image était répétitive. Nous avons donc créé un composant Astro pour intégrer des images avec une seule ligne de code.

<Pic filename="day1/inner-frame" role="presentation" />

Utilisateurs de lecteurs d'écran et de claviers

L'expérience Designcember se déroule en grande partie à travers les fenêtres artistiques et interactives. Il était important pour nous qu'un utilisateur de clavier puisse utiliser le site et jeter un coup d'œil dans les fenêtres, et que les utilisateurs de lecteurs d'écran bénéficient d'une expérience agréable.

Par exemple, lors de l'intégration des images, nous avons utilisé role="presentation" pour marquer l'image comme étant de présentation pour les lecteurs d'écran. Nous avons estimé qu'une expérience utilisateur avec entre 5 et 12 descriptions alt serait mauvaise. Nous avons donc marqué les images comme étant de présentation et fourni une narration globale de la fenêtre. La navigation dans les fenêtres avec un lecteur d'écran donne une impression de narration agréable, ce qui, nous l'espérions, contribuerait à transmettre l'humour et le plaisir que le site souhaite partager.

La vidéo suivante présente une démonstration de l'expérience clavier. Les touches de tabulation, Entrée, barre d'espace et Échap sont toutes utilisées pour déplacer le curseur vers et depuis les pop-ups et les fenêtres.

L'expérience de lecture d'écran comporte des attributs ARIA spéciaux qui clarifient le contenu. Par exemple, les liens pour les jours indiquent uniquement "un" ou "deux", mais avec l'ajout d'ARIA, ils sont annoncés comme "Jour 1" et "Jour 2". De plus, toutes les images sont résumées dans un seul libellé, de sorte que chaque fenêtre dispose d'une description.

Astro, générateur de sites statiques axé sur les composants

Astro a permis à l'équipe de travailler facilement ensemble sur le site. Le modèle de composant était familier aux développeurs Angular et React, tandis que le système de style de nom de classe à portée limitée a permis à chaque développeur de savoir que son travail sur une fenêtre n'entrerait pas en conflit avec celui d'un autre.

Jours en tant que composants

Chaque jour était un composant qui récupérait l'état d'un magasin de données au moment de la compilation. Cela nous a permis d'exécuter la logique du modèle avant que le code HTML n'atteigne le navigateur. La logique déterminerait si le jour doit afficher son info-bulle ou non, car les jours inactifs n'ont pas de pop-up.

Les compilations sont exécutées toutes les heures, et le datastore de durée de compilation débloque un nouveau jour lorsque le serveur de compilation a dépassé minuit. Ces petits systèmes autonomes et à mise à jour automatique permettent de maintenir le site à jour.

Styles limités et Open Props

Astro étend les styles écrits dans son modèle de composants, ce qui a facilité la répartition de la charge de travail entre plusieurs membres de l'équipe et a également rendu l'utilisation d'Open Props amusante. Les styles Open Props normalize.css se sont avérés utiles avec le thème adaptatif (clair et sombre), ainsi que pour gérer le contenu comme les paragraphes et les en-têtes.

En tant que premiers utilisateurs d'Astro, nous avons rencontré quelques problèmes avec PostCSS. Par exemple, nous n'avons pas pu passer à la dernière version d'Astro en raison d'un trop grand nombre de problèmes de compilation. Vous pouvez passer plus de temps à optimiser les workflows de compilation et de développement.

Conteneurs flexibles

Certaines fenêtres s'agrandissent et se réduisent, en conservant les proportions pour préserver leur aspect. Nous avons utilisé d'autres fenêtres pour illustrer la puissance de l'architecture basée sur les composants avec des requêtes de conteneur. Les requêtes de conteneur permettaient aux fenêtres de posséder leurs propres informations de style responsif et de se réajuster en fonction de leur taille. Certaines fenêtres sont passées d'étroites à larges et ont dû ajuster la taille et l'emplacement du contenu multimédia qu'elles contenaient.

Démonstration de la façon dont les fenêtres changent lorsqu&#39;elles ont plus d&#39;espace.

À mesure que davantage d'espace devient disponible pour une fenêtre, nous pouvons adapter la taille ou les éléments enfants de la fenêtre pour qu'ils s'y ajustent. Il s'est avéré que pour répondre aux fenêtres adaptatives, les requêtes de conteneur ne seraient pas seulement amusantes à présenter, mais qu'elles seraient nécessaires et simplifieraient considérablement l'orchestration de certaines mises en page.

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

Cette approche est différente de celle qui consiste à conserver un format. Elle offre plus de contrôle et plus d'opportunités. À une certaine taille, de nombreux enfants se déplacent pour s'adapter à une nouvelle disposition.

Les requêtes de conteneur nous ont également permis de prendre en charge le confinement dans le sens du bloc (vertical). Ainsi, à mesure qu'une fenêtre s'allongeait, nous pouvions ajuster ses styles pour qu'elle s'adapte correctement. Cela se voit dans les requêtes basées sur la hauteur, que nous avons utilisées de manière autonome et en plus des requêtes basées sur la largeur :

.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);
  }
}

Nous avons également utilisé des requêtes de conteneur pour afficher et masquer les détails à mesure que l'illustration devenait de plus en plus encombrée à des tailles plus petites et plus vide à des tailles plus grandes. La fenêtre 9 est un excellent exemple de la façon dont cela s'est produit :

Compatibilité entre navigateurs

Pour créer une expérience moderne et performante sur plusieurs navigateurs, en particulier pour les API expérimentales comme les requêtes de conteneur, nous avons besoin d'un excellent polyfill. Nous avons fait appel à notre équipe, et Surma a dirigé la création d'un nouveau polyfill de requête de conteneur. Le polyfill s'appuie sur ResizeObserver, MutationObserver et la fonction CSS :is(). Par conséquent, tous les navigateurs modernes sont compatibles avec le polyfill, en particulier Chrome et Edge à partir de la version 88, Firefox à partir de la version 78 et Safari à partir de la version 14. L'utilisation du polyfill permet d'utiliser l'une des syntaxes suivantes :

/* These are all equivalent */
@container (min-width: 200px) {
  /* ... */
}
@container (width >= 200px) {
  /* ... */
}
@container size(width >= 200px) {
  /* ... */
}

Mode sombre

Versions en mode clair et sombre du site Designcember, côte à côte.

Une dernière touche essentielle pour le site Web Designcember était un magnifique thème sombre. Nous voulions montrer comment vous pouviez utiliser l'art lui-même pour participer activement à la création d'une expérience en mode sombre de qualité. Pour ce faire, nous avons ajusté les styles d'arrière-plan de chaque fenêtre de manière programmatique et utilisé autant de CSS que possible lors de la création de l'illustration de la fenêtre. La plupart des arrière-plans étaient des dégradés CSS, ce qui permettait d'ajuster plus facilement leurs valeurs de couleur. Nous avons ensuite superposé les illustrations.

Autres easter eggs

Touche personnelle

Nous avons ajouté quelques touches personnelles à la page pour donner plus de personnalité au site. La première était la distribution des personnages, inspirée de notre équipe. Nous avons également inclus un curseur de style rétro pour les jours d'inactivité et modifié le style de la favicon.

Styles de curseur et options de favicon personnalisés

Touches fonctionnelles

L'une des fonctionnalités supplémentaires est la fonction "Revenir à aujourd'hui", avec un oiseau perché sur le toit du bâtiment. En cliquant sur cet oiseau ou en appuyant sur Entrée, vous êtes redirigé vers le jour actuel du mois sur la page, ce qui vous permet d'accéder rapidement aux dernières nouveautés.

Le site Web Designcember propose également une feuille de style d'impression spéciale où nous fournissons essentiellement une image spécifique qui fonctionne le mieux sur du papier de 21,6 x 27,9 cm.Vous pouvez ainsi imprimer le calendrier vous-même et rester dans l'esprit des fêtes tout au long de l'année.

Impression grand format du design de l&#39;agenda.
Una tenant une grande impression de l'agenda.

En résumé, nous avons déployé beaucoup d'efforts pour créer une expérience Web moderne, amusante et fantaisiste afin de célébrer le développement d'UI tout au long du mois de décembre. Nous espérons qu'elle vous a plu.

Parties de l&#39;agenda avec des annotations et des notes visuelles