Ein Einblick in den Prozess und die Tools, die für die Erstellung des Designcember-Designs im Stil eines Feiertagskalenders verwendet wurden.
Im Dezember und in Anlehnung an die vielen Kalender, mit denen Nutzer den Countdown bis zum Fest herunterzählen, möchten wir Webinhalte aus der Community und vom Chrome-Team vorstellen. Jeden Tag haben wir einen UI-Entwicklungs- und designbezogenen Inhalt hervorgehoben. Insgesamt waren das 31 Highlights, darunter 26 neue Demo-Websites, Tools, Ankündigungen, Podcasts, Videos, Artikel und Fallstudien.
Das vollständige Angebot finden Sie unter designcember.com.
Übersicht
Unser Ziel war es, eine barrierefreie, skurrile, moderne und responsive Website mit möglichst wenigen Byte zu erstellen. Wir wollten neue responsive APIs wie Containerabfragen vorstellen und ein schönes Beispiel für einen dunklen Modus in eine designorientierte Website mit vielen Assets aufnehmen. Dazu haben wir unter anderem Dateien komprimiert, mehrere Formate angeboten, Build-Tools verwendet, die für die Generierung statischer Websites optimiert sind, und eine neue Polyfill-Funktion ausgeliefert.
Mit skurrilen Inhalten beginnen
Die Designcember-Kalender-Website diente als Schaufenster für alle Projekte, die wir im Dezember vorstellen wollten, und diente gleichzeitig als Demo-Website. Wir haben uns für ein responsives Wohnhaus entschieden, das höher und schmaler oder kürzer und breiter werden kann, mit Fenstern, die sich innerhalb des Frames neu anordnen. Jedes Fenster entsprach einem Tag (und damit einem Inhalt). Gemeinsam mit der Illustratorin Alice Lee haben wir unsere Vision zum Leben erweckt.
Alice war inspirierend und teilte Prozesse und Skizzen, die schon in ihren ersten Konzepten spannend waren. Während sie an den Bildern arbeitete, haben wir an der Architektur gefeilt. Die ersten Diskussionen drehten sich um das Makro-Layout, das Gebäude und seine Fenster. Wie würden sich die Fenster an eine größere Ansicht anpassen, wenn mehr Platz im Ansichtsbereich zur Verfügung steht? Wie weit könnten sie schrumpfen oder dehnen? Wie groß darf das Gebäude maximal sein? Wie stark würden sich die Fenster verschieben?
Hier sehen Sie eine Vorschau eines responsiven Prototyps mit grid-auto-flow: dense
, der zeigt, wie Fenster automatisch durch den Rasteralgorithmus platziert werden können. Wir haben schnell gemerkt, dass diese Raster zwar gut geeignet sind, um Artwork zu präsentieren, aber nicht die Möglichkeit bieten, die Fenster in einem nicht einheitlichen verfügbaren Bereich zu vergrößern und zu verkleinern und die Vorteile von Containerabfragen zu demonstrieren.
Sobald das allgemeine Raster relativ stabil war und eine gewisse Richtung für die Reaktionsfähigkeit des Gebäudes und seiner Fenster vermittelte, konnten wir uns auf ein einzelnes Fenster konzentrieren. Einige Fenster wurden mehr als andere im Raster gedehnt, verkleinert, zusammengepresst, vergrößert und neu zusammengesetzt.
Jedes Fenster müsste mit einer gewissen Unruhe beim Ändern der Größe umgehen. Unten sehen Sie einen Prototyp eines Fensters, der seine Reaktion auf Turbulenzen veranschaulicht. Er zeigt, wie stark sich jedes interaktive Fenster anpassen könnte.
Fensteranimation mit Spritesheets
Einige Fenster haben Animationen, die die Interaktion verbessern. Die Animationen werden in Photoshop von Hand und Frame für Frame gezeichnet. Jeder Frame wird exportiert, mit diesem Spritesheet-Generator in ein Spritesheet umgewandelt und dann mit Squoosh optimiert. Für die CSS-Animation werden dann background-position-x
und animation-timing-function
verwendet, 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%; }
}
Einige Animationen, wie die Spardose von Tag 6, waren schrittweise CSS-Animationen.
Wir haben diesen Effekt mit einer ähnlichen Technik mit steps()
erzielt, mit dem Unterschied, dass die keyframes CSS-Transformierungspositionen anstelle von Hintergrundpositionen waren.
CSS-Maskierung
Einige Fenster hatten eine einzigartige Form. Wir haben
Masken und
aspect-ratio
verwendet, um ein skalierbares, individuell geformtes und anpassbares Fenster zu erstellen.
Um eine Maske wie diese für Windows 8 zu erstellen, waren einige klassische Photoshop-Kenntnisse sowie ein wenig Wissen darüber erforderlich, wie Masken im Web funktionieren. Sehen wir uns das Zeitfenster für Tag acht an.
Damit die innere Form, die einem Kleeblatt ähnelt, als Maske verwendet werden kann, muss sie als eigene Form isoliert und mit der Farbe Weiß gefüllt werden. Weiß teilt dem CSS mit, welche Inhalte beibehalten werden, und alles außerhalb der weißen nicht. In Photoshop wurde das Innere des Fensters ausgewählt, um 1 Pixel geglättet (um Aliasing-Probleme zu entfernen), dann weiß ausgefüllt und mit derselben Höhe und Breite wie der Fensterrahmen exportiert. Auf diese Weise konnten der Frame und die Maske direkt übereinander gelegt werden, sodass der innere Inhalt innerhalb des Frames erwartungsgemäß sichtbar war.
Sobald der Vorgang abgeschlossen ist, kann der Inhalt des Fensters geändert werden und bleibt immer im benutzerdefinierten Frame. Das folgende Bild zeigt die Version des Fensters im Dunkelmodus mit einem anderen Hintergrundverlauf und einem CSS-Glühen-Filter, der auf die Lampe angewendet wird.
Die Maskierung unterstützt auch responsive, containerabfragebasierte Fenster. In Fenster 9 befindet sich ein Zeichen, das sich hinter einer Maske verbirgt, bis das Fenster eine schmalere Größe hat. Damit der Nutzer das Bild nicht außerhalb des Frames anpassen kann, hat Alice die gesamte Figur für uns fertiggestellt. Die Figur ist im Fenster maskiert, die Pflanzen jedoch nicht. Eine weitere Herausforderung bestand darin, maskierte Elemente mit nicht maskierten Ebenen zu überlagern und dafür zu sorgen, dass sie alle gut zusammen skaliert werden.
Das folgende Bild zeigt, wie es ohne die Maske am Fenster und am Charakter aussehen würde.
Bild verkleinern
Um die Genauigkeit der Illustration beizubehalten und zu verhindern, dass die Bilder auf High-Definition-Bildschirmen unscharf werden, arbeitete Alice mit einem 3-fachen Pixelverhältnis. Der Plan bestand darin, imgix zu verwenden und optimierte Bilder und Formate auf dem Server bereitzustellen. Wir stellten jedoch fest, dass wir durch die manuelle Feinabstimmung mit dem Squoosh-Tool mindestens 50% sparen konnten.
Bei der Komprimierung von Illustrationen gibt es besondere Herausforderungen, insbesondere bei Pinselstrichen und dem transparenten Stil mit rauen Kanten, den Alice verwendet hat. Wir haben jedes der dreimal aus Photoshop exportierten PNG-Bilder mit Squoosh in ein kleineres PNG-, WebP- und AVIF-Bild umgewandelt. Jeder Dateityp verfügt über spezielle Komprimierungsfunktionen. Mehr als 50 Bilder mussten komprimiert werden, um gängige Optimierungseinstellungen zu finden.
Die Squoosh-Befehlszeile war entscheidend, da über 200 Bilder optimiert werden mussten. Die manuelle Optimierung hätte Tage gedauert. Nachdem wir die gemeinsamen Optimierungseinstellungen festgelegt hatten, haben wir sie als Befehlszeilenanweisungen bereitgestellt und ganze Ordner mit PNG-Bildern in ihre komprimierten WebP- und AVIF-Äquivalente umgewandelt.
Hier ist ein Beispiel für einen verwendeten AVIF-Befehl in der Squoosh-Befehlszeile:
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
Wenn die optimierte Artwork-Datei in das Repository eingecheckt war, könnten wir mit dem Laden der Bilder aus HTML beginnen:
<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 Bild-Quellcodes war repetitiv. Deshalb haben wir eine Astro-Komponente entwickelt, mit der Bilder mit einer Codezeile eingebettet werden können.
<Pic filename="day1/inner-frame" role="presentation" />
Nutzer von Screenreadern und Tastaturen
Ein Großteil des Designcember-Erlebnisses besteht aus Kunst und interaktiven Fenstern. Für uns war es wichtig, dass Tastaturnutzer die Website verwenden und in Fenster schauen können und dass Screenreader-Nutzer gute Erzählungen erhalten.
Beim Einbetten der Bilder haben wir beispielsweise role="presentation"
verwendet, um das Bild für Screenreader als „präsentationsorientiert“ zu kennzeichnen. Wir waren der Meinung, dass eine Nutzererfahrung mit 5 bis 12 zerbrochenen alt
-Beschreibungen nicht optimal ist. Deshalb haben wir die Bilder als Präsentationselemente gekennzeichnet und eine allgemeine Fensterbeschreibung hinzugefügt. Das Wechseln zwischen den Fenstern mit einem Screenreader hat dann einen schönen narrativen Charakter, was uns hoffentlich dabei helfen wird, die Verspieltheit und den Spaß zu vermitteln, die die Website vermitteln möchte.
Im folgenden Video sehen Sie eine Demo der Tastatur. Mithilfe der Tabulatortaste, der Eingabe-, Leertaste und der Escape-Taste wird der Fokus zwischen den Pop-ups und den Fenstern und umgekehrt orchestriert.
Für Screenreader gibt es spezielle ARIA-Attribute, die für Klarheit bei den Inhalten sorgen. Die Links für die Tage enthalten beispielsweise nur „Eins“ oder „Zwei“, werden aber mithilfe von ARIA als „Tag 1“ und „Tag 2“ angesagt. Darüber hinaus werden alle Bilder in einem einzigen Label zusammengefasst, sodass jedes Fenster eine Beschreibung hat.
Komponentengesteuerter Websitegenerator für Astro, statische zuerst
Astro erleichterte es dem Team, gemeinsam an der Website zu arbeiten. Das Komponentenmodell war sowohl Angular- als auch React-Entwicklern vertraut, während das Stilsystem der auf einen Bereich reduzierten Klassennamen jedem Entwickler half, zu erkennen, dass seine Arbeit an einem Fenster nicht mit anderen in Konflikt geraten würde.
Tage als Komponenten
Jeder Tag war eine Komponente, die den Status aus einem Build-Time-Datenspeicher abgerufen hat. So konnten wir die Vorlagenlogik ausführen, bevor die HTML-Daten den Browser erreichten. Die Logik würde bestimmen, 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 Datenspeicher für die Buildzeit würde einen neuen Tag entsperren, wenn der Buildserver nach Mitternacht war. Mit diesen kleinen Systemen, die automatisch aktualisiert werden, ist die Website immer auf dem neuesten Stand.
Stilblöcke und Open Props
Die Stile von Astroskopen wurden im Komponentenmodell geschrieben, was die Verteilung der Arbeitslast auf viele Teammitglieder vereinfachte. Außerdem machte die Verwendung von Open Props Spaß. Die Stile Open Props normalize.css waren beim adaptiven Design (hell und dunkel) sehr nützlich und erleichterten die Codierung von Inhalten wie Absätzen und Überschriften.
Als frühe Nutzer von Astro sind wir auf einige Probleme mit PostCSS gestoßen. So konnten wir beispielsweise aufgrund zu vieler Build-Probleme nicht auf die aktuelle 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 oder verkleinert, wobei das Seitenverhältnis beibehalten wird, um die Kunstwerke zu erhalten. In einigen anderen Fenstern haben wir die Leistungsfähigkeit der komponentenbasierten Architektur mit Containerabfragen demonstriert. Containerabfragen bedeuteten, dass Fenster eigene Informationen zu responsiven Stilen besitzen und an ihre eigene Größe anpassen konnten. Einige Fenster wurden von schmal zu breit und es musste die Größe der darin enthaltenen Medien sowie deren Platzierung angepasst werden.
Wenn mehr Platz für ein Fenster verfügbar ist, können wir die Größe oder die untergeordneten Elemente des Fensters entsprechend anpassen. Es stellte sich heraus, dass zur Erfüllung der adaptiven Fenster Container-Abfragen nicht nur Spaß machen würden, sondern auch erforderlich wären und die Orchestrierung bestimmter Layouts erheblich vereinfachen würde.
.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 eines Seitenverhältnisses. Sie bietet mehr Kontrolle und mehr Möglichkeiten. Ab einer bestimmten Größe rücken viele Kinder um, um sich an ein neues Layout anzupassen.
Containerabfragen ermöglichten auch die Unterstützung von Begrenzungen in Blockrichtung (vertikal). So konnten wir seine Stile entsprechend anpassen, wenn ein Fenster immer länger wurde. Das ist bei den absatzbasierten Abfragen zu sehen, die wir eigenständig und zusätzlich zu den 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 ein- und auszublenden, da die Grafik bei kleineren Größen immer überladener und bei größeren leerer wurde. Fenster 9 ist ein gutes Beispiel dafür:
Browserübergreifende Unterstützung
Um eine moderne, plattformübergreifende Umgebung zu schaffen, insbesondere für experimentelle APIs wie Containerabfragen, benötigen wir eine gute polyfill. Wir haben unser Team um Hilfe gebeten und Surma hat die Leitung für den Build einer neuen Containerabfrage-Polyfill übernommen. Die Polyfill-Funktion setzt ResizeObserver, MutationObserver und die CSS-Funktion :is() voraus. Daher wird die Polyfill von allen modernen Browsern unterstützt, insbesondere von Chrome und Edge ab Version 88, Firefox ab Version 78 und Safari ab Version 14. Bei Verwendung des Polyfills ist jede der folgenden Syntaxen möglich:
/* These are all equivalent */
@container (min-width: 200px) {
/* ... */
}
@container (width >= 200px) {
/* ... */
}
@container size(width >= 200px) {
/* ... */
}
Dunkler Modus
Ein letzter wichtiger Punkt für die Designcember-Website war ein schönes dunkles Design. Wir wollten zeigen, wie Sie mit Kunst einen Dark Mode gestalten können, der Ihnen gefällt. Dazu haben wir die Hintergrundstile der einzelnen Fenster programmatisch angepasst und beim Erstellen des Artworks so viel CSS wie sinnvoll verwendet. Bei den meisten Hintergründen handelte es sich um CSS-Verläufe, sodass die Farbwerte einfacher angepasst werden können. Darauf haben wir dann die Grafik gelegt.
Weitere Ostereier
Persönliche Details
Wir haben der Seite einige persönliche Elemente hinzugefügt, um ihr mehr Persönlichkeit zu verleihen. Das erste war die Besetzung der Charaktere, die von unserem Team inspiriert wurde. Außerdem haben wir an Tagen ohne Aktivität einen Cursor im Retro-Stil hinzugefügt und mit dem Favicon-Stil experimentiert.
Funktionelle Elemente
Eine der zusätzlichen Funktionen ist die Funktion „Zu heute springen“ mit einem Vogel auf dem Gebäude. Wenn du auf diesen Vogel klickst oder die Eingabetaste drückst, gelangst du auf der Seite zum aktuellen Tag des Monats, sodass du schnell zu den neuesten Produktveröffentlichungen gelangst.
Designcember.com hat auch ein spezielles Druck-Stylesheet, in dem wir im Grunde ein bestimmtes Bild bereitstellen, das am besten auf Papier im Format 21,6 × 27,9 cm funktioniert.So können Sie den Kalender selbst ausdrucken und das ganze Jahr über festlich feiern.
Insgesamt wurde im Dezember intensiv in die Entwicklung einer lustigen, skurrilen modernen Web-Umgebung investiert, um die Entwicklung der Benutzeroberfläche zu feiern. Wir hoffen, es hat dir gefallen!