Gebäudeentwurf

Ein Blick auf den Prozess und die Tools, die zum Erstellen des Adventskalenders von Designcember verwendet wurden.

Im Dezember und angesichts der vielen Kalender, die zum Herunterzählen und Feiern verwendet werden, möchten wir Web-Inhalte der Community und des Chrome-Teams hervorheben. Jeden Tag haben wir einen Beitrag zu UI-Entwicklung und Design veröffentlicht. Insgesamt gab es 31 Beiträge, darunter 26 neue Demowebsites, Tools, Ankündigungen, Podcasts, Videos, Artikel und Fallstudien.

designcember.com

Die Designcember-Website.

Übersicht

Unser Ziel war es, eine zugängliche, verspielte, moderne und responsive Weboberfläche mit möglichst wenigen Bytes zu schaffen. Wir wollten neue responsive APIs wie Container-Abfragen hervorheben und ein schönes Beispiel für den Dark Mode auf einer designorientierten und assetreichen Website zeigen. Dazu haben wir Dateien komprimiert, mehrere Formate angeboten, Build-Tools verwendet, die für die Generierung statischer Websites optimiert sind, ein neues Polyfill bereitgestellt und vieles mehr.

Mit einer Laune beginnen

Die Idee hinter der Designcember-Kalenderwebsite war, sie als Schaufenster für alle Arbeiten zu nutzen, die wir im Dezember präsentieren wollten, und gleichzeitig als Demowebsite zu fungieren. Wir haben uns für ein responsives Wohngebäude entschieden, das höher und schmaler oder niedriger und breiter werden kann und dessen Fenster sich im Rahmen neu anordnen. Jedes Fenster stand für einen Tag und damit für einen Inhalt. Wir haben mit der Illustratorin Alice Lee zusammengearbeitet, um unsere Vision zu verwirklichen.

Skizzen des Seitengerüsts für Designcember.

Alice war inspirierend und teilte Prozesse und Skizzen, die schon in ihren frühen Konzepten spannend waren. Während sie an der Grafik arbeitete, haben wir an der Architektur gearbeitet. Die ersten Diskussionen drehten sich um das Makrolayout, das Gebäude und seine Fenster. Wie würden sich die Fenster an eine, zwei oder drei Spalten anpassen, wenn mehr Platz im Viewport verfügbar wäre? Wie weit können sie schrumpfen oder sich dehnen? Wie groß darf das Gebäude maximal sein? Wie stark würden sich die Zeiträume verschieben?

Hier sehen Sie eine Vorschau eines responsiven Prototyps mit grid-auto-flow: dense, in dem Fenster automatisch vom Grid-Algorithmus platziert werden. Wir haben schnell festgestellt, dass sich Raster mit Seitenverhältnis zwar hervorragend eignen, um Kunstwerke zu präsentieren, aber nicht die Möglichkeit bieten, die Fenster in ungleichmäßig verfügbaren Platz ein- und auszublenden und die Leistungsfähigkeit von Containerabfragen zu demonstrieren.

Animation, die zeigt, wie dieser Wireframe auf verschiedene Bildschirmgrößen reagiert.
Demo auf CodePen ansehen

Als das allgemeine Raster relativ stabil war und eine Richtung für die Reaktionsfähigkeit des Gebäudes und seiner Fenster vorgab, konnten wir uns auf ein einzelnes Fenster konzentrieren. Einige Fenster wurden im Raster mehr als andere gestreckt, verkleinert, zusammengedrückt, vergrößert und neu zusammengesetzt.

Wireframes, die zeigen, wie die Fenster bei verschiedenen Breakpoints angezeigt werden.

Jedes Fenster muss eine bestimmte Anzahl von Größenänderungen bewältigen können. Unten sehen Sie einen Prototyp eines Fensters, das auf Turbulenzen reagiert. Er zeigt, wie stark sich die einzelnen interaktiven Fenster anpassen.

Fensteranimation mit Spritesheets

Einige Fenster haben Animationen, um die Interaktion zu verbessern. Die Animationen werden in Photoshop Frame für Frame von Hand gezeichnet. Jeder Frame wird exportiert, mit diesem Spritesheet-Generator in ein Spritesheet umgewandelt und dann mit Squoosh optimiert. Die CSS-Animation verwendet dann background-position-x und animation-timing-function, wie im folgenden Beispiel gezeigt.

.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, die das Zeitfenster für den ersten Tag zeigt.

Einige Animationen, z. B. das Sparschwein am sechsten Tag, waren schrittbasierte CSS-Animationen. Wir haben diesen Effekt mit einer ähnlichen Technik erzielt, bei der steps() verwendet wurde. Der Unterschied besteht darin, dass die Keyframes CSS-Transformationspositionen und keine Hintergrundpositionen waren.

CSS-Maskierung

Einige Fenster hatten einzigartige Formen. Wir haben Masken und aspect-ratio verwendet, um ein skalierbares, einzigartig geformtes und adaptives Fenster zu erstellen.

Um eine Maske wie diese für Fenster 8 zu erstellen, waren einige klassische Photoshop-Kenntnisse sowie ein wenig Wissen über die Funktionsweise von Masken im Web erforderlich. Sehen wir uns das Fenster für den achten Tag an.

Das Fenster für den achten Tag.

Damit die innere vierblättrige Kleeblattform zu einer Maske wird, muss sie als eigene Form isoliert und weiß gefüllt werden. Mit Weiß wird dem CSS mitgeteilt, welche Inhalte beibehalten werden sollen. Alles außerhalb des weißen Bereichs wird nicht beibehalten. In Photoshop wurde das Innere des Fensters ausgewählt, mit 1 Pixel weichgezeichnet (um Aliasing-Probleme zu vermeiden), dann weiß gefüllt und mit derselben Höhe und Breite wie der Fensterrahmen exportiert. So konnten der Frame und die Maske direkt übereinander gelegt werden, sodass der innere Inhalt wie erwartet im Frame angezeigt wurde.

Bild mit Kleeblattmaske

Nach Abschluss des Vorgangs konnte der Inhalt des Fensters geändert werden und blieb immer innerhalb des benutzerdefinierten Rahmens. Das folgende Bild zeigt die Version des Fensters im dunklen Modus mit einem anderen Hintergrundgradienten und einem CSS-Filter für das Glühen, der auf die Lichtquelle angewendet wird.

Das Fenster für den achten Tag im dunklen Modus.

Die Maskierung unterstützt auch responsive Fenster, die auf Containerabfragen basieren. In Fenster 9 ist eine Figur zu sehen, die hinter einer Maske verborgen ist, bis das Fenster schmaler wird. Damit der Nutzer das Bild nicht außerhalb des Rahmens anpassen kann, hat Alice die gesamte Figur für uns fertiggestellt. Die Figur wird im Fenster maskiert, die Pflanzen jedoch nicht. Eine weitere Herausforderung bestand also darin, maskierte Elemente mit nicht maskierten Ebenen zu kombinieren und dafür zu sorgen, dass sie alle gut skaliert werden.

Das folgende Bild zeigt, wie es ohne die Maske auf dem Fenster und der Figur aussieht.

Das Bild für Fenster 9 ohne Maske.

Kunstwerke zusammenquetschen

Um die Qualität der Illustration beizubehalten und dafür zu sorgen, dass Nutzer mit hochauflösenden Bildschirmen keine verschwommene Darstellung sehen, arbeitete Alice mit einem 3-fachen Pixelverhältnis. Wir wollten imgix verwenden, um optimierte Bilder und Formate auf dem Server bereitzustellen. Wir haben jedoch festgestellt, dass wir durch manuelle Anpassungen mit dem Squoosh-Tool 50% oder mehr einsparen können.

Bilder mit Squoosh komprimieren

Illustrationen stellen besondere Herausforderungen für die Komprimierung dar, insbesondere der von Alice verwendete Pinselstrich und der transparente, raue Rand. Wir haben jedes PNG-Bild, das mit Photoshop im 3-fachen Format exportiert wurde, mit Squoosh in ein kleineres PNG-, WebP- und AVIF-Bild umgewandelt. Jeder Dateityp hat seine eigenen speziellen Komprimierungsfunktionen. Es waren mehr als 50 Bilder erforderlich, um einige gemeinsame Optimierungseinstellungen zu finden.

Die Squoosh CLI war entscheidend, da über 200 Bilder optimiert werden mussten. Das manuelle Optimieren hätte Tage gedauert. Nachdem wir die allgemeinen Optimierungseinstellungen hatten, haben wir sie als Befehlszeilenanweisungen bereitgestellt und ganze Ordner mit PNG-Bildern in ihre WebP- und AVIF-komprimierten Pendants umgewandelt.

Hier ist ein Beispiel für einen AVIF-CLI-Squoosh-Befehl:

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

Nachdem die optimierten Grafiken im Repository eingecheckt wurden, konnten wir sie aus HTML laden:

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

Das Schreiben des Quellcodes für Bilder war repetitiv. Daher haben wir eine Astro-Komponente erstellt, mit der Bilder mit einer Zeile Code eingebettet werden können.

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

Screenreader- und Tastaturnutzer

Ein Großteil der Designcember-Erfahrung besteht aus Kunst und interaktiven Fenstern. Es war uns wichtig, dass Nutzer, die eine Tastatur verwenden, die Website nutzen und in die Fenster schauen können und dass Screenreader-Nutzer eine gute Sprachausgabe erhalten.

Beim Einbetten der Bilder haben wir beispielsweise role="presentation" verwendet, um das Bild für Screenreader als präsentationsbezogen zu kennzeichnen. Wir waren der Meinung, dass eine Nutzererfahrung mit 5 bis 12 fragmentierten alt-Beschreibungen schlecht sein würde. Daher haben wir die Bilder als präsentationsfähig markiert und eine allgemeine Fenstererzählung hinzugefügt. Das Durchgehen der Fenster mit einem Screenreader fühlt sich dann wie eine Geschichte an. Wir hofften, dass dies dazu beitragen würde, die Verspieltheit und den Spaß zu vermitteln, die die Website vermitteln soll.

Im folgenden Video sehen Sie eine Demo der Tastatur. Die Tab-, Eingabe-, Leer- und Esc-Taste werden verwendet, um den Fokus auf und von den Fenster-Pop-ups und den Fenstern zu verschieben.

Für Screenreader gibt es spezielle ARIA-Attribute, die für Klarheit bei den Inhalten sorgen. Die Links für die Tage lauten beispielsweise nur „eins“ oder „zwei“. Mit ARIA werden sie jedoch als „Tag 1“ und „Tag 2“ angekündigt. Außerdem werden alle Bilder unter einem einzigen Label zusammengefasst, sodass jedes Fenster eine Beschreibung hat.

Astro, statischer, komponentengesteuerter Site-Generator

Astro hat die Zusammenarbeit im Team an der Website erleichtert. Das Komponentenmodell war sowohl Angular- als auch React-Entwicklern vertraut. Das System für klassennamen mit Bereich half jedem Entwickler, dass seine Arbeit an einem Fenster nicht mit der anderer in Konflikt geraten würde.

Tage als Komponenten

Jeder Tag war eine Komponente, die den Status aus einem Datenspeicher für die Build-Zeit abgerufen hat. So konnten wir die Vorlagenlogik ausführen, bevor das HTML den Browser erreichte. Die Logik würde festlegen, ob für den Tag eine Kurzinfo angezeigt werden soll oder nicht, da für inaktive Tage keine Pop-ups angezeigt werden.

Builds werden stündlich ausgeführt und der Build-Zeit-Datenspeicher wird für einen neuen Tag freigeschaltet, wenn der Build-Server nach Mitternacht ist. Diese kleinen, sich selbst aktualisierenden und autarken Systeme sorgen dafür, dass die Website auf dem neuesten Stand bleibt.

Bereichsbezogene Stile und Open Props

Astro beschränkt Stile auf das Komponentmodell, was die Verteilung der Arbeitslast auf viele Teammitglieder erleichtert und die Verwendung von Open Props angenehmer macht. Die Open Props normalize.css-Stile waren für das adaptive (helle und dunkle) Design sehr nützlich und haben auch bei der Gestaltung von Inhalten wie Absätzen und Überschriften geholfen.

Als Early Adopter von Astro sind wir auf einige Probleme mit PostCSS gestoßen. Beispielsweise konnten wir aufgrund zu vieler Build-Probleme nicht auf die neueste Astro-Version aktualisieren. Hier könnte mehr Zeit für die Optimierung der Build- und Entwickler-Workflows aufgewendet werden.

Flexible Container

Einige Fenster werden vergrößert und verkleinert, wobei das Seitenverhältnis beibehalten wird, um die Kunstwerke zu erhalten. Wir haben einige andere Fenster verwendet, um die Leistungsfähigkeit der komponentenbasierten Architektur mit Containerabfragen zu demonstrieren. Mit Containerabfragen konnten Fenster ihre eigenen responsiven Stilinformatioen haben und sich an ihre eigene Größe anpassen. Einige Fenster wurden von schmal zu breit geändert. Daher musste die Größe der darin enthaltenen Media sowie deren Platzierung angepasst werden.

Eine Demonstration, wie sich die Fenster verändern, wenn sie mehr Platz haben.

Wenn mehr Platz für ein Fenster verfügbar wird, können wir die Größe oder untergeordneten Elemente des Fensters anpassen. Es stellte sich heraus, dass Containerabfragen nicht nur eine gute Möglichkeit sind, adaptive Fenster zu präsentieren, sondern auch erforderlich sind und die Orchestrierung bestimmter Layouts erheblich vereinfachen.

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

Dieser Ansatz unterscheidet sich vom Beibehalten des Seitenverhältnisses. Sie bietet mehr Kontrolle und mehr Möglichkeiten. Ab einer bestimmten Größe passen sich viele Kinder an ein neues Layout an.

Containerabfragen haben es uns auch ermöglicht, die Blockrichtung (vertikal) zu unterstützen. Wenn ein Fenster also länger wurde, konnten wir seine Stile entsprechend anpassen. Das zeigt sich in den höhenbasierten Abfragen, die wir eigenständig und zusätzlich zu breitenbasierten Abfragen verwendet haben:

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

Außerdem haben wir Containerabfragen verwendet, um Details je nach Größe des Bildes ein- oder auszublenden. Fenster 9 ist ein gutes Beispiel dafür:

Browserübergreifende Unterstützung

Um eine moderne, browserübergreifende Nutzerfreundlichkeit zu schaffen, insbesondere für experimentelle APIs wie Containerabfragen, benötigen wir ein gutes Polyfill. Wir haben unser Team informiert und Surma hat einen Build für ein neues Container-Query-Polyfill entwickelt. Das Polyfill basiert auf ResizeObserver, MutationObserver und der CSS-Funktion :is(). Daher unterstützen alle modernen Browser das Polyfill, insbesondere Chrome und Edge ab Version 88, Firefox ab Version 78 und Safari ab Version 14. Durch die Verwendung des Polyfills sind die folgenden Syntaxen möglich:

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

Dunkler Modus

Die Versionen der Designcember-Website im hellen und dunklen Modus nebeneinander.

Ein letzter wichtiger Punkt für die Designcember-Website war ein ansprechendes dunkles Design. Wir wollten zeigen, wie Sie selbst durch Kunst zu einem ansprechenden Dark Mode beitragen können. Dazu haben wir die Hintergrundstile der einzelnen Fenster programmatisch angepasst und beim Erstellen der Fenstergrafiken so viel CSS wie möglich verwendet. Die meisten Hintergründe waren CSS-Verläufe, damit ihre Farbwerte leichter angepasst werden konnten. Darüber haben wir dann die Grafiken gelegt.

Weitere Easter Eggs

Persönliche Note

Wir haben der Seite einige persönliche Elemente hinzugefügt, um ihr mehr Persönlichkeit zu verleihen. Das Erste war die Besetzung, die von unserem Team inspiriert wurde. Außerdem haben wir an inaktiven Tagen einen Cursor im Retro-Stil eingeführt und mit dem Favicon-Stil experimentiert.

Benutzerdefinierte Cursorstile und Favicon-Optionen

Funktionale Berührungen

Eine der zusätzlichen Funktionen ist „Zum heutigen Tag springen“ mit einem Vogel, der auf dem Gebäude sitzt. Wenn Sie auf diesen Vogel klicken oder die Eingabetaste drücken, werden Sie auf der Seite zum aktuellen Tag des Monats weitergeleitet, sodass Sie schnell zu den neuesten Veröffentlichungen gelangen.

Auf Designcember.com gibt es auch ein spezielles Stylesheet für den Druck, mit dem wir im Grunde ein bestimmtes Bild bereitstellen, das am besten auf Papier mit den Maßen 8,5 × 11 Zoll passt.So können Sie den Kalender selbst ausdrucken und das ganze Jahr über in festlicher Stimmung bleiben.

Ein Poster des Kalenderdesigns.
Una hält einen großen Ausdruck des Kalenders in der Hand.

Insgesamt haben wir viel Arbeit in die Entwicklung einer unterhaltsamen, skurrilen modernen Weboberfläche gesteckt, um den ganzen Dezember über die UI-Entwicklung zu feiern. Wir hoffen, es hat dir gefallen.

Teile des Kalenders mit Anmerkungen und visuellen Notizen