Projektant budynku

Wgląd w proces i narzędzia użyte do stworzenia kalendarza adwentowego Designcember.

W grudniu, kiedy wiele osób korzysta z kalendarzy, aby odliczać dni do świąt i je świętować, chcieliśmy wyróżnić treści internetowe od społeczności i zespołu Chrome. Codziennie wyróżnialiśmy 1 materiał związany z projektowaniem i tworzeniem interfejsów. W sumie było ich 31, w tym 26 nowych witryn demonstracyjnych, narzędzi, ogłoszeń, podcastów, filmów, artykułów i studiów przypadku.

Pełną wersję znajdziesz na stronie designcember.web.app.

Witryna Designcember.

Przegląd

Naszym celem było stworzenie dostępnej, zabawnej, nowoczesnej i działającej na różnych urządzeniach witryny, która zajmuje jak najmniej miejsca. Chcieliśmy zwrócić uwagę na nowe interfejsy API, takie jak zapytania o kontener, i pokazać piękny przykład trybu ciemnego na stronie internetowej z dużą ilością zasobów i skupionej na projektowaniu. W tym celu skompresowaliśmy pliki, udostępniliśmy wiele formatów, użyliśmy narzędzi do kompilacji zoptymalizowanych pod kątem generowania statycznych witryn, wprowadziliśmy nowy polyfill i zrobiliśmy wiele innych rzeczy.

Zacznij od fantazji

Strona kalendarza Designcember miała być miejscem, w którym prezentujemy wszystkie prace, na które chcieliśmy zwrócić uwagę w grudniu, a jednocześnie pełnić funkcję witryny demonstracyjnej. Postanowiliśmy zbudować elastyczny budynek mieszkalny, który mógłby być wyższy i węższy lub niższy i szerszy, z oknami, które same zmieniałyby swoje położenie w ramach. Każde okienko reprezentowało 1 dzień (a więc 1 element treści). Współpracowaliśmy z ilustratorką Alice Lee, aby zrealizować naszą wizję.

Szkice szkieletu strony Designcember.

Alice była inspirująca, dzieliła się procesami i szkicami, które były ekscytujące nawet na wczesnych etapach. Gdy ona pracowała nad grafiką, my zajmowaliśmy się architekturą. W początkowych rozmowach skupialiśmy się na ogólnym układzie, budynku i jego oknach. Jak okna dostosowywałyby się do jednej, dwóch lub trzech kolumn, gdyby było dostępne więcej miejsca w obszarze wyświetlania? Jak bardzo mogą się skurczyć lub rozciągnąć? Jaki byłby maksymalny rozmiar budynku? O ile przesuną się okna?

Oto podgląd elastycznego prototypu z grid-auto-flow: dense, który pokazuje, jak algorytm siatki może automatycznie rozmieszczać okna. Szybko zdaliśmy sobie sprawę, że chociaż siatki oparte na proporcjach obrazu świetnie nadają się do prezentowania grafiki, nie dają możliwości powiększania i zmniejszania okien w nierównomiernie dostępnej przestrzeni ani nie pokazują możliwości zapytań o kontenery.

Animacja pokazująca, jak ten szkielet reaguje na różne rozmiary ekranu.
Wypróbuj tę wersję demonstracyjną w CodePen

Gdy ogólna siatka była już względnie stabilna i przekazywała poczucie kierunku reakcji budynku i jego okien, mogliśmy skupić się na jednym oknie. Niektóre okna w siatce rozciągały się, kurczyły, ściskały, powiększały i przekształcały bardziej niż inne.

Makiety pokazujące, jak okna wyświetlają się w różnych punktach przerwania.

Każde okno musi radzić sobie z określoną liczbą zmian rozmiaru. Poniżej znajduje się prototyp okna pokazujący jego reakcję na turbulencje i to, jak bardzo każde interaktywne okno może się dostosować.

Animacja okna z arkuszami sprite’ów

Niektóre okna mają animacje, które zwiększają interaktywność. Animacje są rysowane ręcznie, klatka po klatce, w programie Photoshop. Każda klatka jest eksportowana, przekształcana w arkusz sprite’ów za pomocą tego generatora arkuszy sprite’ów, a następnie optymalizowana za pomocą Squoosh. Animacja CSS używa następnie background-position-xanimation-timing-function, jak pokazano w tym przykładzie.

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

Animacja pokazująca okno pierwszego dnia.

Niektóre animacje, np. skarbonka z szóstego dnia, były animacjami CSS opartymi na krokach. Uzyskaliśmy ten efekt za pomocą podobnej techniki, używając steps(), z tą różnicą, że klatki kluczowe były pozycjami przekształcenia CSS, a nie pozycjami tła.

Maskowanie CSS

Niektóre okna miały nietypowe kształty. Użyliśmy masekaspect-ratio, aby stworzyć skalowalne, unikalne w kształcie i adaptacyjne okno.

Aby utworzyć maskę, taką jak ta dla okna 8, potrzebne były klasyczne umiejętności obsługi programu Photoshop oraz odrobina wiedzy o tym, jak działają maski w internecie. Spójrzmy na okienko z 8 dnia.

Okno na 8 dzień.

Aby stać się maską, wewnętrzny kształt czterolistnej koniczyny musi być wyodrębniony jako osobny kształt i wypełniony kolorem białym. Biały kolor określa, które treści mają pozostać, a wszystko poza tym zostanie usunięte. W programie Photoshop wybrano wnętrze okna, zastosowano rozmycie o wartości 1 piksela (aby usunąć problemy z aliasingiem), a następnie wypełniono je białym kolorem i wyeksportowano z tą samą wysokością i szerokością co ramka okna. W ten sposób ramka i maska mogą być nałożone bezpośrednio na siebie, a wewnętrzna zawartość ramki będzie wyświetlana zgodnie z oczekiwaniami.

Obraz maski z koniczyną

Po zakończeniu tego procesu zawartość okna może zostać zmodyfikowana i zawsze będzie się wyświetlać w ramce niestandardowej. Obraz poniżej przedstawia wersję okna w trybie ciemnym z innym gradientem tła i filtrem CSS blasku zastosowanym do światła.

Okno ósmego dnia w trybie ciemnym.

Maskowanie obsługuje też okna oparte na zapytaniach o kontenery elastyczne. W oknie 9 postać jest ukryta za maską, dopóki okno nie będzie węższe. Aby mieć pewność, że użytkownik nie będzie mógł przesunąć obrazu poza ramkę, Alice dokończyła rysowanie postaci. Postać jest zamaskowana w oknie, ale rośliny nie, więc kolejnym wyzwaniem było dla nas nałożenie zamaskowanych elementów na niezamaskowane warstwy i zapewnienie, że wszystkie będą się dobrze skalować.

Na tym obrazie widać, jak wyglądałoby okno i postać bez maski.

Obraz okna 9 bez maski.

Rozciąganie grafiki

Aby zachować wierność ilustracji i zapewnić, że na ekranach o wysokiej rozdzielczości nie będzie ona rozmyta, Alice pracowała w stosunku pikseli 3x. Planowaliśmy używać imgix i wyświetlać zoptymalizowane obrazy i formaty na naszym serwerze, ale okazało się, że ręczne dostosowywanie za pomocą narzędzia Squoosh może zaoszczędzić nam 50% lub więcej.

Kompresowanie obrazów za pomocą Squoosh.

Ilustracje stanowią wyjątkowe wyzwanie dla kompresji, zwłaszcza w przypadku stylu pociągnięć pędzla i przezroczystych, nierównych krawędzi, którego użyła Alice. Każdy obraz PNG wyeksportowany z Photoshopa w rozmiarze 3x przekonwertowaliśmy na mniejszy plik PNG, WebP i AVIF. Każdy typ pliku ma własne możliwości kompresji. Aby znaleźć wspólne ustawienia optymalizacji, skompresowaliśmy ponad 50 obrazów.

Squoosh CLI stał się kluczowym narzędziem, gdy trzeba było zoptymalizować ponad 200 obrazów. Ręczne wykonanie tego zadania zajęłoby kilka dni. Po ustaleniu wspólnych ustawień optymalizacji przekazaliśmy je jako instrukcje w wierszu poleceń i przetworzyliśmy wsadowo całe foldery obrazów PNG na ich skompresowane odpowiedniki w formatach WebP i AVIF.

Oto przykład użytego polecenia AVIF CLI squoosh:

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

Po sprawdzeniu zoptymalizowanych grafik w repozytorium możemy zacząć je wczytywać z 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>

Pisanie kodu źródłowego obrazu było powtarzalne, więc utworzyliśmy komponent Astro, aby osadzać obrazy za pomocą jednego wiersza kodu.

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

Użytkownicy czytników ekranu i klawiatur

Większość atrakcji Designcember to dzieła sztuki i interaktywne wystawy. Zależało nam na tym, aby użytkownicy klawiatury mogli korzystać z witryny i podglądać okna, a użytkownicy czytników ekranu mogli cieszyć się przyjemnym doświadczeniem.

Na przykład podczas osadzania obrazów użyliśmy atrybutu role="presentation", aby oznaczyć obraz jako prezentacyjny dla czytników ekranu. Uznaliśmy, że wrażenia użytkowników, którzy muszą przeczytać od 5 do 12 fragmentów opisów alt, będą negatywne. Dlatego oznaczyliśmy obrazy jako prezentacyjne i dodaliśmy ogólną narrację okna. Przechodzenie między oknami za pomocą czytnika ekranu daje wrażenie płynnej narracji, co, jak mieliśmy nadzieję, pomoże przekazać kapryśność i zabawę, które strona chce udostępnić.

Poniższy film przedstawia demonstrację działania klawiatury. Klawisze Tab, Enter, spacja i Escape służą do przenoszenia zaznaczenia między wyskakującymi okienkami a oknami.

Czytnik ekranu ma specjalne atrybuty ARIA, które ułatwiają zrozumienie treści. Na przykład linki do dni zawierają tylko słowa „jeden” lub „dwa”, ale po dodaniu atrybutów ARIA są odczytywane jako „Dzień pierwszy” i „Dzień drugi”. Poza tym wszystkie obrazy są podsumowane w jednej etykiecie, dzięki czemu każde okno ma opis.

Astro, statyczny generator witryn oparty na komponentach

Astro ułatwił zespołowi współpracę nad witryną. Model komponentów był znany zarówno programistom Angulara, jak i Reakta, a system stylów z zakresem nazw klas pomagał każdemu programiście mieć pewność, że jego praca nad oknem nie będzie kolidować z pracą innych osób.

Dni jako komponenty

Każdy dzień był komponentem, który pobierał stan z magazynu danych czasu kompilacji. Dzięki temu mogliśmy uruchamiać logikę szablonu, zanim kod HTML dotarł do przeglądarki. Logika określa, czy w danym dniu ma się wyświetlać etykietka, ponieważ nieaktywne dni nie mają wyskakujących okienek.

Kompilacje są uruchamiane co godzinę, a magazyn danych czasu kompilacji odblokowuje nowy dzień, gdy serwer kompilacji przekroczy północ. Te małe, samoczynnie aktualizujące się i samowystarczalne systemy dbają o to, aby witryna była aktualna.

Style ograniczone do zakresu i Open Props

Astro zakresuje style zapisane w modelu komponentu, co ułatwiało rozdzielanie pracy między członków zespołu i sprawiało, że korzystanie z Open Props było przyjemne. Style Open Props normalize.css okazały się przydatne w przypadku adaptacyjnego motywu (jasnego i ciemnego), a także pomogły w zarządzaniu treściami, takimi jak akapity i nagłówki.

Jako pierwsi użytkownicy Astro napotkaliśmy kilka problemów z PostCSS. Na przykład nie udało nam się zaktualizować do najnowszej wersji Astro z powodu zbyt wielu problemów z kompilacją. Można tu poświęcić więcej czasu na optymalizację kompilacji i procesów programistycznych.

Elastyczne kontenery

Niektóre okna powiększają się i zmniejszają, zachowując współczynnik proporcji, aby nie zniekształcić obrazu. Użyliśmy innych okien, aby zaprezentować możliwości architektury opartej na komponentach z zapytaniami o kontenery. Zapytania o kontener oznaczają, że okna mogą mieć własne informacje o stylach responsywnych i dostosowywać się do własnych rozmiarów. Niektóre okna zmieniły się z wąskich na szerokie, więc trzeba było dostosować rozmiar multimediów w nich wyświetlanych, a także ich położenie.

Demonstracja, jak zmieniają się okna, gdy mają więcej miejsca.

Gdy okno ma więcej miejsca, możemy dostosować jego rozmiar lub elementy podrzędne. Okazało się, że aby w pełni wykorzystać adaptacyjne okna, zapytania o kontenery nie tylko będą ciekawym rozwiązaniem, ale też będą wymagane i znacznie uproszczą koordynowanie niektórych układów.

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

To podejście różni się od zachowania proporcji obrazu. Daje większą kontrolę i więcej możliwości. Gdy dziecko osiągnie określony rozmiar, często zmienia pozycję, aby dostosować się do nowego układu.

Zapytania o kontener pozwoliły nam też obsługiwać ograniczenie w kierunku bloku (pionowym), dzięki czemu wraz ze wzrostem długości okna mogliśmy dostosowywać jego style. Widać to w przypadku zapytań dotyczących wysokości, których używaliśmy samodzielnie i w połączeniu z zapytaniami dotyczącymi szerokości:

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

Użyliśmy też zapytań o kontener, aby pokazywać i ukrywać szczegóły, gdy grafika stawała się coraz bardziej zatłoczona przy mniejszych rozmiarach i coraz bardziej pusta przy większych rozmiarach. Okno 9 to świetny przykład, jak to działa:

Obsługa różnych przeglądarek

Aby zapewnić nowoczesne działanie w różnych przeglądarkach, zwłaszcza w przypadku eksperymentalnych interfejsów API, takich jak zapytania o kontenery, potrzebujemy dobrego polyfillu. Zwróciliśmy się do naszego zespołu, a Surma stanął na czele prac nad nowym wypełnieniem zapytań o kontenery. Polyfill korzysta z interfejsów ResizeObserverMutationObserver oraz z funkcji CSS:is(). Dlatego wszystkie nowoczesne przeglądarki obsługują polyfill, w szczególności Chrome i Edge od wersji 88, Firefox od wersji 78 oraz Safari od wersji 14. Korzystanie z polyfillu umożliwia używanie dowolnej z tych składni:

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

Tryb ciemny

Wersje witryny Designcember w trybie jasnym i ciemnym wyświetlane obok siebie.

Ostatnim elementem, który był niezbędny w przypadku witryny Designcember, był piękny ciemny motyw. Chcieliśmy pokazać, jak można wykorzystać sztukę, aby aktywnie uczestniczyć w tworzeniu świetnego trybu ciemnego. W tym celu programowo dostosowaliśmy style tła każdego okna i użyliśmy jak najwięcej kodu CSS, aby stworzyć grafikę okna. Większość tła była gradientami CSS, co ułatwiało dostosowywanie wartości kolorów. Następnie nałożyliśmy na nie grafikę.

Inne ukryte żarty

Osobiste akcenty

Dodaliśmy do strony kilka elementów, które nadają jej bardziej osobisty charakter. Pierwszym z nich była obsada, która powstała na podstawie inspiracji naszego zespołu. Dodaliśmy też kursor w stylu retro w dniach bez aktywności i eksperymentowaliśmy ze stylem ikony.

Niestandardowe style kursora i opcje ikony witryny

Funkcjonalne detale

Jednym z dodatkowych elementów jest funkcja „Przejdź do dziś” z ptakiem siedzącym na dachu budynku. Kliknięcie tego ptaka lub naciśnięcie klawisza Enter powoduje przejście do bieżącego dnia miesiąca, dzięki czemu możesz szybko sprawdzić najnowsze premiery.

Na stronie Designcember znajduje się też specjalny arkusz stylów do drukowania, w którym wyświetlamy konkretny obraz, który najlepiej wygląda na papierze o wymiarach 21,6 cm x 27,9 cm.Możesz samodzielnie wydrukować kalendarz i cieszyć się świąteczną atmosferą przez cały rok.

Wydruk projektu kalendarza w formacie plakatu.
Una trzyma duży wydruk kalendarza.

W grudniu włożyliśmy mnóstwo pracy w stworzenie zabawnej, fantazyjnej i nowoczesnej strony internetowej, aby przez cały miesiąc świętować rozwój interfejsu. Mamy nadzieję, że Ci się spodobało.

Fragmenty kalendarza z adnotacjami i notatkami wizualnymi