Uno sguardo al processo e agli strumenti utilizzati per creare l'esperienza di Designcember in stile calendario delle festività.
In vista del mese di dicembre e dei molti calendari che le persone utilizzano per il conto alla rovescia e le celebrazioni, abbiamo voluto mettere in evidenza i contenuti web della community e del team di Chrome. Ogni giorno abbiamo messo in evidenza un contenuto relativo allo sviluppo e al design dell'interfaccia utente, per un totale di 31 notizie, tra cui 26 nuovi siti demo, strumenti, annunci, podcast, video, articoli e case study.
Per scoprire l'esperienza completa, visita il sito designcember.com.
Panoramica
Il nostro obiettivo era offrire un'esperienza web accessibile, stravagante, moderna e adattabile con il minor numero di byte possibile. Volevamo mettere in evidenza nuove API adattabili come le query dei contenitori e includere un bell'esempio di modalità oscura in un sito web incentrato sul design e con molti asset. Per raggiungere questo obiettivo, abbiamo compresso i file, offerto più formati, utilizzato strumenti di compilazione ottimizzati per la generazione di siti statici, rilasciato un nuovo polyfill e altro ancora.
Iniziare con la fantasia
L'idea alla base del sito del calendario di Designcember era fungere da vetrina per tutto il lavoro che volevamo mettere in evidenza durante il mese di dicembre, fungendo al contempo da sito demo. Abbiamo deciso di costruire un condominio adattabile che potesse essere più alto e stretto o più basso e largo, con finestre che si riorganizzavano all'interno del telaio. Ogni finestra rappresentava un giorno (e quindi un contenuto). Per dare vita alla nostra visione, abbiamo collaborato con l'illustratrice Alice Lee.
Alice è stata una fonte di ispirazione, condividendo procedure e schizzi entusiasmanti anche nelle prime fasi di ideazione. Mentre lei lavorava all'artwork, noi ci occupavamo dell'architettura. Le prime discussioni riguardavano il layout generale, l'edificio e le sue finestre. In che modo le finestre si adattano a una, due o tre colonne man mano che diventa disponibile più spazio nella visualizzazione? Fino a che punto possono restringersi o allungarsi? Quali sono le dimensioni massime dell'edificio? Di quanto si sposterebbero le finestre?
Ecco un'anteprima di un prototipo adattabile che utilizza grid-auto-flow: dense
che mostra come le finestre potrebbero essere posizionate automaticamente dall'algoritmo della griglia. Abbiamo capito subito che, sebbene le griglie con proporzioni fossero perfette per mettere in evidenza le immagini, non offrivano la possibilità di far crescere e rimpicciolire le finestre in uno spazio disponibile non uniforme e di mostrare la potenza delle query dei contenitori.
Una volta che la griglia generale era relativamente stabile e comunicava un senso di direzione per la reattività dell'edificio e delle sue finestre, abbiamo potuto concentrarci su una singola finestra. Alcune finestre si sono allungate, rimpicciolite, compresse, ingrandite e ricomposte più di altre nella griglia.
Ogni finestra dovrebbe gestire una certa quantità di turbolenza di ridimensionamento. Di seguito è riportato un prototipo di una finestra che dimostra la sua reattività alle turbolenze, mostrando quanto ci si può aspettare che ogni finestra interattiva si adatti.
Animazione della finestra con spritesheet
Alcune finestre hanno animazioni per rendere l'esperienza più interattiva. Le animazioni sono disegnate a mano, frame per frame, in Photoshop. Ogni frame viene esportato, trasformato in uno spritesheet con questo
generatore di spritesheet e poi ottimizzato con Squoosh. L'animazione CSS utilizza quindi background-position-x
e
animation-timing-function
, come mostrato nell'esempio seguente.
.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%; }
}
Alcune animazioni, come la salvadanaio del sesto giorno, erano animazioni CSS basate su passaggi.
Abbiamo ottenuto questo effetto con una tecnica simile, utilizzando steps()
, con la differenza che i fotogrammi chiave erano posizioni di trasformazione CSS anziché posizioni di sfondo.
Mascheramento CSS
Alcune finestre avevano forme uniche. Abbiamo utilizzato
maschere e
aspect-ratio
per creare una finestra adattabile, dalla forma unica e scalabile.
Per creare una maschera, come questa per la finestra 8, sono state necessarie alcune competenze classiche di Photoshop, più un po' di conoscenza del funzionamento delle maschere sul web. Diamo un'occhiata alla finestra per l'ottavo giorno.
Per diventare una maschera, la forma interna a forma di quadrifoglio deve essere isolata come forma a sé stante e riempita di bianco. Il bianco indica al CSS quali contenuti rimangono e tutto ciò che non è bianco non viene visualizzato. In Photoshop, l'interno della finestra è stato selezionato, sfumato di 1 px (per rimuovere i problemi di aliasing), poi riempito di bianco ed esportato con le stesse altezza e larghezza del telaio della finestra. In questo modo, il frame e la maschera possono essere sovrapposti direttamente l'uno all'altro, mostrando i contenuti interni all'interno del frame come previsto.
Al termine, i contenuti della finestra possono essere modificati e appariranno sempre all'interno del frame personalizzato. L'immagine seguente mostra la versione della finestra in modalità Buio, con un gradiente di sfondo diverso e un filtro CSS di illuminazione applicato alla luce.
Il mascheramento supporta anche finestre responsive basate su query del contenitore. Nella finestra 9, un personaggio è nascosto dietro una maschera finché la finestra non è più stretta. Per assicurarci che l'utente non possa modificare l'immagine fuori dall'inquadratura, Alice ha completato il personaggio per noi. Il personaggio è mascherato all'interno della finestra, ma non le piante, quindi un'altra sfida che abbiamo dovuto affrontare è stata sovrapporre elementi mascherati a livelli non mascherati e assicurarci che tutti avessero una buona scalabilità.
L'immagine seguente mostra l'aspetto senza la maschera sulla finestra e sul personaggio.
Squooshing the art
Per mantenere la fedeltà dell'illustrazione e garantire un'esperienza utente nitida sugli schermi ad alta definizione, Alice ha lavorato con un rapporto di pixel di 3 volte. Il piano era utilizzare imgix e pubblicare immagini e formati ottimizzati sul suo server, ma abbiamo scoperto che le modifiche manuali con lo strumento Squoosh potevano farci risparmiare almeno il 50%.
L'illustrazione presenta sfide uniche per la compressione, in particolare la pennellata e lo stile con bordi frastagliati trasparenti utilizzati da Alice. Abbiamo scelto di comprimere ogni immagine PNG estratta da Photoshop 3 volte in un'immagine PNG, WebP e AVIF più piccola. Ogni tipo di file ha le sue capacità di compressione speciali e ci è voluto più di 50 immagini compresse per trovare alcune impostazioni di ottimizzazione comuni.
La CLI di Squioosh è diventata fondamentale con oltre 200 immagini da ottimizzare: farlo manualmente avrebbe richiesto giorni. Una volta ottenute le impostazioni di ottimizzazione comuni, le abbiamo fornite come istruzioni della riga di comando ed elaborato in batch intere cartelle di immagini PNG nelle relative versioni compresse WebP e AVIF.
Ecco un esempio di comando squoosh della CLI AVIF utilizzato:
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
Dopo aver inserito gli artwork ottimizzati nel repository, possiamo iniziare a caricarli da 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>
Scrivere il codice sorgente delle immagini era ripetitivo, quindi abbiamo creato un componente Astro per incorporare le immagini con una riga di codice.
<Pic filename="day1/inner-frame" role="presentation" />
Utenti di screen reader e tastiera
Gran parte dell'esperienza di Designcember si basa sulle illustrazioni e sulle finestre interattive. Per noi era importante che un utente con tastiera potesse utilizzare il sito e dare un'occhiata alle finestre e che gli utenti di screen reader potessero usufruire di un'esperienza di narrazione piacevole.
Ad esempio, quando abbiamo incorporato le immagini, abbiamo utilizzato role="presentation"
per contrassegnarle come di presentazione per gli screen reader. Riteniamo che un'esperienza utente con 5-12 descrizioni alt
frazionate non sia ottimale. Pertanto, abbiamo contrassegnato le immagini come di presentazione e fornito una narrazione complessiva della finestra. Spostarsi tra le finestre con uno screen reader offre un'esperienza narrativa piacevole, che speravamo potesse contribuire a trasmettere la stravaganza e il divertimento che il sito vuole condividere.
Il video seguente mostra una demo dell'esperienza con la tastiera. I tasti Tab, Invio, Barra spaziatrice ed ESC vengono utilizzati per gestire lo stato attivo tra i popup e le finestre.
L'esperienza dello screen reader ha attributi ARIA speciali che chiariscono i contenuti. Ad esempio, i link per i giorni riportano solo "uno" o "due", ma con alcune informazioni ARIA aggiunte, vengono annunciati come "Giorno 1" e "Giorno 2". Inoltre, tutte le immagini sono riassunte in un'unica etichetta, quindi ogni finestra ha una descrizione.
Astro, generatore di siti basato su componenti e statico
Astro ha permesso al team di collaborare facilmente al sito. Il modello di componenti era familiare sia agli sviluppatori Angular che a quelli React, mentre il sistema di stile del nome della classe con ambito aiutava ogni sviluppatore a sapere che il proprio lavoro in una finestra non entrava in conflitto con quello di altri.
Giorni come componenti
Ogni giorno era un componente che recuperava lo stato da un datastore del momento di compilazione. In questo modo, abbiamo potuto eseguire la logica del modello prima che il codice HTML raggiungesse il browser. La logica determinerà se mostrare o meno la descrizione comando del giorno, poiché i giorni inattivi non hanno popup.
Le build vengono eseguite ogni ora e l'archivio dati dei tempi di compilazione sblocca un nuovo giorno quando il server di compilazione è passato la mezzanotte. Questi piccoli sistemi auto-aggiornabili e autosufficienti mantengono il sito aggiornato.
Stili basati su ambito e componenti Open Props
Astro esamina gli stili scritti all'interno del suo modello di componenti, il che ha semplificato la distribuzione del carico di lavoro tra molti membri del team e ha reso divertente l'utilizzo di Open Props. Gli stili normalize.css di Open Props sono stati utili con il tema adattivo (chiaro e scuro) e hanno aiutato a gestire i contenuti come paragrafi e intestazioni.
Come early adopter di Astro, abbiamo riscontrato alcuni problemi con PostCSS. Ad esempio, non è stato possibile eseguire l'aggiornamento all' ultima versione di Astro a causa di troppi problemi di compilazione. Potrebbe essere speso più tempo qui, ottimizzando i flussi di lavoro di compilazione e degli sviluppatori.
Contenitori flessibili
Alcune finestre si espandono e si restringono, mantenendo le proporzioni per preservare l'artwork. Abbiamo utilizzato altre finestre per mostrare la potenza dell'architettura basata su componenti con le query dei container. Le query del contenitore consentivano alle finestre di avere le proprie informazioni di stile responsive e di adeguarsi in base alle proprie dimensioni. Alcune finestre sono passate da strette a larghe ed è stato necessario regolare le dimensioni dei contenuti multimediali al loro interno, nonché il loro posizionamento.
Man mano che diventa disponibile più spazio per una finestra, potremmo adattare le dimensioni o gli elementi secondari della finestra in modo che si inseriscano. È emerso che, per soddisfare le finestre adattabili, le query dei contenitori non sarebbero state solo divertenti da mostrare, ma sarebbero state necessarie e avrebbero semplificato drasticamente l'orchestrazione di determinati layout.
.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;
}
}
Questo approccio è diverso dal mantenere le proporzioni. Offre più controllo e più opportunità. A una certa dimensione, molti bambini si spostano per adattarsi a un nuovo layout.
Le query dei contenitori ci hanno anche permesso di supportare il contenimento in base alla direzione del blocco (verticale), quindi, man mano che una finestra aumentava di lunghezza, potevamo modificare i relativi stili in modo che si adattassero in modo appropriato. Questo si verifica nelle query basate sull'altezza, che abbiamo utilizzato in modo autonomo, e oltre alle query basate sulla larghezza:
.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);
}
}
Abbiamo anche utilizzato le query dei contenitori per mostrare e nascondere i dettagli man mano che l'illustrazione diventava sempre più affollata a dimensioni ridotte e più vuota a dimensioni più grandi. La finestra 9 è un ottimo esempio di come questo approccio è stato utilizzato:
Supporto su più browser
Per creare un'esperienza moderna e multibrowser, in particolare per le API sperimentali come le query dei contenitori, abbiamo bisogno di un ottimo polyfill. Abbiamo lanciato un appello al nostro team e Surma ha guidato la creazione di un nuovo polyfill per le query dei contenitori. Il polyfill si basa su ResizeObserver, MutationObserver e sulla funzione:is() CSS. Pertanto, tutti i browser moderni supportano il polyfill, in particolare Chrome e Edge dalla versione 88, Firefox dalla versione 78 e Safari dalla versione 14. L'utilizzo del polyfill consente una delle seguenti sintassi:
/* These are all equivalent */
@container (min-width: 200px) {
/* ... */
}
@container (width >= 200px) {
/* ... */
}
@container size(width >= 200px) {
/* ... */
}
Modalità Buio
Un ultimo tocco essenziale per il sito web di Designcember è stato un bellissimo tema scuro. Volevamo mostrare come utilizzare l'arte stessa per partecipare attivamente alla creazione di un'esperienza eccezionale con la modalità oscura. Per farlo, abbiamo modificato i CSS di sfondo di ogni finestra in modo programmatico e abbiamo utilizzato il maggior numero di CSS possibile durante la creazione della grafica della finestra. La maggior parte degli sfondi era costituita da sfumature CSS, in modo da poter regolare più facilmente i relativi valori di colore. Poi abbiamo sovrapposto l'illustrazione.
Altri easter egg
Tocchi personali
Abbiamo aggiunto alcuni tocchi personali alla pagina per dare al sito più personalità. Il primo è stato il cast di personaggi, ispirato dal nostro team. Abbiamo anche incluso un cursore in stile retrò nei giorni di inattività e abbiamo sperimentato con lo stile della favicon.
Tocchi funzionali
Uno dei tocchi funzionali aggiuntivi è la funzionalità "Vai a oggi", con un uccello che si trova in cima all'edificio. Se fai clic o premi Invio su questo uccello, nella pagina viene visualizzato il giorno corrente del mese, in modo da poter accedere rapidamente agli ultimi lanci.
Designcember.com ha anche uno stile di stampa speciale in cui viene visualizzata un'immagine specifica che funziona meglio su carta da 21,6 x 28 cm, in modo da poter stampare il calendario e mantenere l'atmosfera festosa tutto l'anno.
Tutto sommato, è stato necessario un sacco di lavoro per creare un'esperienza web moderna, divertente e stravagante per celebrare lo sviluppo dell'interfaccia utente per tutto il mese di dicembre. Ci auguriamo che sia stato di tuo gradimento.