Projektant budynku

Wgląd w proces i narzędzia użyte do stworzenia Designcember w stylu kalendarza świątecznego.

W duchu grudnia i wielu kalendarzy, których ludzie używają do odliczania i obchodów, chcemy wyróżnić treści internetowe od społeczności i zespołu Chrome. Każdego dnia prezentowaliśmy jeden materiał dotyczący rozwoju i projektowania interfejsu użytkownika. Łącznie było to 31 materiałów, w tym 26 nowych witryn demonstracyjnych, narzędzi, ogłoszeń, podcastów, filmów, artykułów i studiów przypadków.

Pełną wersję znajdziesz na stronie designcember.com.

Witryna Designcember.

Przegląd

Naszym celem było zapewnienie dostępności, nowoczesności, nowoczesności i responsywności w jak najmniejszej ilości bajtów. Chcieliśmy pokazać nowe interfejsy API do obsługi elastycznych interfejsów, takie jak zapytania dotyczące kontenera, oraz podać piękny przykład trybu ciemnego w witrynie, która stawia na design i zawiera wiele komponentów. Aby to osiągnąć, skompresowaliśmy pliki, zaoferowaliśmy kilka formatów, użyliśmy narzędzi do kompilacji zoptymalizowanych pod kątem generowania witryn statycznych, wprowadziliśmy nowe narzędzie polyfill i wykonaliśmy wiele innych działań.

Zaczynanie od kaprysu

Idea strony Designcember polegała na tym, aby była ona miejscem, w którym prezentujemy wszystkie projekty, które chcemy wyróżnić w grudniu, a jednocześnie pełniła funkcję strony demonstracyjnej. Postanowiliśmy stworzyć elastyczny budynek mieszkalny, który może być wyższy i węższy lub niższy i szerszy, a okna mogą się przestawiać w ramce. Każde okno reprezentowało 1 dzień (czyli 1 element treści). Aby zrealizować naszą wizję, współpracowaliśmy z ilustratorką Alice Lee.

Szkic szkieletu strony Designcember.

Alice była inspirująca. Udostępniła procesy i szkice, które były ekscytujące nawet na etapie wczesnych koncepcji. Podczas gdy ona pracowała nad grafiką, my zajmowaliśmy się architekturą. Na początku dyskutowaliśmy o makrostrukturze, budynku i jego oknach. Jak okna dostosowują się do jednej, dwóch lub trzech kolumn, gdy dostępnej przestrzeni w widoku jest więcej? Jak bardzo mogą się kurczyć lub rozciągać? Jaki jest maksymalny rozmiar budynku? O ile przesuną się okna?

Oto podgląd elastycznego prototypu w wersji grid-auto-flow: dense, który pokazuje, jak okna mogą być automatycznie umieszczane przez algorytm siatki. Szybko zdaliśmy sobie sprawę, że choć siatki z uwzględnieniem proporcji dają świetne efekty w przypadku grafiki, nie pozwalają na powiększanie i pomniejszanie okien w niejednorodzonym dostępnym obszarze oraz nie pokazują potencjału zapytań kontenerowych.

Animacja pokazująca, jak ten wireframe reaguje na różne rozmiary ekranu.
Sprawdź ten przykład na CodePen.

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

Szkic przedstawiający sposób wyświetlania okien w różnych punktach przełamania.

Każde okno musiałoby obsługiwać pewną ilość zmian rozmiaru. Poniżej znajduje się prototyp okna, który pokazuje, jak reaguje ono na turbulencje i jak bardzo może się zmieniać.

Animacja okna z arkuszami sprite

Niektóre okna zawierają animacje, które zwiększają interaktywność. Animacje są rysowane ręcznie w programie Photoshop. Każdy kadr jest eksportowany i zamieniany w arkusz sprite’ów za pomocą tego generatora arkuszy sprite’ów, a następnie optymalizowany za pomocą Squoosh. Animacja CSS używa wtedy wartości background-position-xanimation-timing-function, jak 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 w pierwszym dniu.

Niektóre animacje, np. skarbonka z 6 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 kluczowe klatki miały pozycje transformacji CSS zamiast pozycji tła.

Maskowanie w CSS

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

Aby utworzyć maskę, taką jak ta dla okna 8, potrzebne były podstawowe umiejętności w Photoshopie oraz odrobina wiedzy o tym, jak działają maski w internecie. Przyjrzyjmy się oknu na 8. dzień.

Okno na 8. dzień.

Aby stać się maską, wewnętrzny kształt typu czterolistna koniczyna musi być wyodrębniony jako osobny kształt i wypełniony na biało. Biały kolor wskazuje porównywarce, które treści mają pozostać, a które nie. W Photoshopie wybrano wnętrze okna, zaokrąglono je o 1 piksel (aby usunąć problemy z aliasowaniem), a następnie wypełniono na biało i wyeksportowano z taką samą wysokością i szerokością jak rama okna. Dzięki temu ramka i maska mogą być nałożone bezpośrednio na siebie, a zawartość wewnątrz ramki będzie wyświetlana zgodnie z oczekiwaniami.

Obraz maski koniczyny

Po zakończeniu procesu można modyfikować zawartość okna, która zawsze będzie się mieścić w ramce niestandardowej. Na poniższym obrazie widać okno w wersji ciemnej z innym gradientem tła i filtrem CSS świecenia zastosowanym do światła.

Okno na 8. dzień w trybie ciemnym.

Maskowanie obsługuje też elastyczne okna oparte na zapytaniu kontenera. W oknie 9 jest postać, która jest ukryta za maską, dopóki okno nie zostanie zwężone. Aby użytkownik nie mógł dostosować obrazu poza kadrem, Alice ukończyła rysowanie całej postaci. Postać jest zamaskowana w oknie, ale rośliny nie są, więc kolejnym wyzwaniem było ułożenie zamaskowanych elementów z niezamaskowanymi warstwami i upewnienie się, że wszystkie są dobrze dopasowane.

Na tym obrazie widać, jak wyglądają okno i postać bez maski.

Obraz okna 9 bez maski.

Squooshing the art

Aby zachować wierność ilustracji i uniknąć rozmyć na ekranach o wysokiej rozdzielczości, Alice pracowała z trzykrotnym współczynnikiem pikseli. Planowaliśmy użyć imgix i przesyłać na serwer tej usługi zoptymalizowane obrazy i formaty, ale okazało się, że ręczne dostosowywanie za pomocą narzędzia Squoosh może przynieść oszczędności rzędu co najmniej 50%.

skompresować obrazy za pomocą Squoosh;

Kompresja ilustracji stwarza wyjątkowe wyzwania, zwłaszcza w przypadku rysunku wykonanego pędzlem i stosowania przez Alice stylu z przezroczystymi nierównymi krawędziami. Zdecydowaliśmy się na użycie Squoosh do zmniejszenia rozmiaru każdego wyeksportowanego z Photoshopa obrazu PNG do 3 x, aby uzyskać mniejsze pliki PNG, WebP i avif. Każdy typ pliku ma swoje specjalne możliwości kompresji. Aby znaleźć typowe ustawienia optymalizacji, musieliśmy skompresować ponad 50 obrazów.

Squoosh CLI stał się niezbędny, gdy trzeba było zoptymalizować ponad 200 obrazów. Robienie tego ręcznie zajęłoby kilka dni. Gdy mieliśmy już wspólne ustawienia optymalizacji, udostępniliśmy je jako instrukcje wiersza poleceń i przeprowadziliśmy grupowe przetwarzanie całych folderów obrazów PNG w wersje skompresowane w formacie WebP i AVIF.

Oto przykład polecenia squoosh w interfejsie wiersza poleceń AVIF:

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 umieszczeniu zoptymalizowanych grafik w repozytorium możemy zacząć ich wczytywanie z pliku 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 obrazów było powtarzalne, więc stworzyliśmy komponent Astro, który umożliwia umieszczanie obrazów za pomocą jednego wiersza kodu.

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

Użytkownicy czytników ekranu i klawiatur

Większość Designcember to grafika i interaktywne okna. Ważne było dla nas, aby użytkownicy korzystający z klawiatury mogli korzystać z witryny i zaglądać do okien, a użytkownicy czytników ekranu mogli korzystać z przyjemnego dźwiękowego opisu.

Na przykład podczas umieszczania obrazów użyliśmy tagu role="presentation", aby oznaczyć obraz jako element prezentacji dla czytników ekranu. Uznaliśmy, że 5–12 rozbitych opisów alt nie zapewni użytkownikom wygodnej obsługi. Dlatego oznaczono je jako obrazy prezentacyjne i dodano do nich ogólny opis. Przechodzenie przez okna za pomocą czytnika ekranu ma przyjemny charakter narracji, co, jak mamy nadzieję, pomoże w przekazaniu szaleństwa i zabawy, które strona chce zaoferować.

Ten film pokazuje demonstrację klawiatury. Klawisze Tab, Enter, Spacja i Escape służą do przenoszenia zaznaczenia na okno wyskakujące i z niego.

Czytniki ekranu mają specjalne atrybuty ARIA, które ułatwiają zrozumienie treści. Na przykład linki do dni zawierają tylko liczby „1” lub „2”, ale dzięki dodatkowym atrybutom ARIA są one ogłaszane jako „Dzień pierwszy” i „Dzień drugi”. Ponadto wszystkie obrazy są podsumowane w jednej etykiecie, dzięki czemu każde okno ma opis.

Astro – generator witryn oparty na komponentach, który najpierw generuje wersję statyczną

Astro ułatwił zespołowi współpracę nad witryną. Model komponentów był znajomy zarówno deweloperom Angulara, jak i Reacta, a system stylów ograniczonych nazw klas pomagał każdemu deweloperowi wiedzieć, ż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 na czas kompilacji. Dzięki temu możemy uruchomić logikę szablonu, zanim kod HTML dotrze do przeglądarki. Logika określa, czy dany dzień ma wyświetlać swój tekst, czy nie, ponieważ w przypadku dni nieaktywnych nie ma wyskakujących okienek.

Kompilacje są wykonywane co godzinę, a magazyn danych z czasem kompilacji odblokowuje nowy dzień, gdy serwer kompilacji przekroczy północ. Te samowystarczalne i samoaktualizujące się systemy dbają o aktualność witryny.

Style ograniczone i otwarte komponenty

Astro stylów w ramach modelu komponentu, co ułatwiło rozłożenie obciążenia pracą na wielu członków zespołu i uprzyjemniło korzystanie z Open Props. Style Open Props normalize.css przydały się do stworzenia motywu dostosowującego się do ekranu (jasnego i ciemnego), a także do zarządzania treściami, takimi jak akapity i nagłówki.

Jako jedni z pierwszych użytkowników Astro napotkaliśmy kilka problemów z PostCSS. Na przykład nie udało nam się zaktualizować do najnowszej wersji Astro z powodu zbyt dużej liczby problemów z kompilacją. W tym przypadku można poświęcić więcej czasu na optymalizację procesu kompilacji i procesów programistycznych.

Elastyczne kontenery

Niektóre okna mogą się powiększać i zmniejszać, zachowując współczynnik proporcji, aby zachować wygląd. Użyliśmy też innych okien, aby pokazać możliwości architektury opartej na komponentach z zapytaniami w kontenerach. Zapytania dotyczące kontenera umożliwiały oknom posiadanie własnych informacji o stylach responsywnych i ich dostosowywanie na podstawie ich rozmiarów. Niektóre okna zmieniły się z wąskich na szerokie, więc trzeba było dostosować rozmiar multimediów w nich oraz ich umiejscowienie.

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

Gdy w oknie będzie dostępne więcej miejsca, możemy dostosować jego rozmiar lub elementy podrzędne. Okazało się, że aby spełnić wymagania dotyczące okien adaptacyjnych, zapytania dotyczące kontenera nie tylko uatrakcyjniałyby prezentację, ale byłyby też wymagane i znacznie upraszczałyby tworzenie określonych 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. Daje ona większą kontrolę i więcej możliwości. W pewnym wieku dzieci zaczynają się przemieszczać, aby dostosować się do nowego układu.

Zapytania o kontenery umożliwiły nam też obsługę ograniczeń w kierunku bloku (pionowo), dzięki czemu w miarę wydłużania okna mogliśmy dostosowywać style do jego rozmiaru. Widać to w zapytaniach opartych na wysokości, które zostały użyte samodzielnie, oraz w zapytaniach opartych na 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ń kontenerowych, aby wyświetlać i ukrywać szczegóły, ponieważ grafika stawała się coraz bardziej zatłoczona w mniejszych rozmiarach, a w większych traciła na gęstości. Okno 9 to świetny przykład, w którym ta funkcja się przydaje:

Obsługa w różnych przeglądarkach

Aby zapewnić nowoczesne działanie w różnych przeglądarkach, zwłaszcza w przypadku eksperymentalnych interfejsów API, takich jak zapytania dotyczące kontenerów, potrzebujemy świetnego rozwiązania polyfill. Wysłaliśmy prośbę do naszego zespołu, a Surma kierował pracami nad nową wersją polyfilla zapytań kontenera. Rozszerzenie polega na ResizeObserver, MutationObserver i funkcji :is() w arkuszu CSS. Dlatego wszystkie nowoczesne przeglądarki obsługują tę funkcję, w szczególności Chrome i Edge od wersji 88, Firefox od wersji 78 i Safari od wersji 14. Dzięki polyfill możesz używać dowolnej z tych składni:

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

Tryb ciemny

Witryna Designcember w wersji jasnej i ciemnej 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ć grafikę, aby aktywnie uczestniczyć w tworzeniu świetnego trybu ciemnego. W tym celu dostosowaliśmy style tła każdego okna programowo i użyliśmy tyle kodu CSS, ile było to sensowne podczas tworzenia grafiki okna. Większość tła była w postaci gradientów CSS, aby ułatwić dostosowanie wartości kolorów. Następnie nałożyliśmy na nie grafikę.

Inne pisanki

elementy osobiste,

Dodaliśmy na stronie kilka elementów, które nadają jej indywidualny charakter. Po pierwsze, obsadę postaci, która powstała dzięki inspiracji od naszego zespołu. W dni bez aktywności dodaliśmy kursor w stylu retro i pobawiliśmy się stylem ikony.

Niestandardowe style kursorów i opcje ikony favicon

Funkcje

Jedną z dodatkowych funkcji jest „Przejdź do dnia dzisiejszego”, która przedstawia ptaka siedzącego na dachu budynku. Kliknięcie tego ptaka lub naciśnięcie klawisza Enter spowoduje przewinięcie strony do bieżącego dnia miesiąca, dzięki czemu możesz szybko przejść do najnowszych gier.

Designcember.com ma też specjalną stronę ze stylem do druku, na której udostępniamy konkretny obraz, który najlepiej sprawdza się na papierze w formacie 8,5 x 11 cm.Dzięki temu możesz samodzielnie wydrukować kalendarz i utrzymać świąteczny nastrój przez cały rok.

wydruk plakatowy projektu kalendarza.
Una trzyma duży wydruk kalendarza.

W sumie włożyliśmy mnóstwo pracy w stworzenie zabawnego, pomysłowego i nowoczesnego interfejsu, który będzie dostępny przez cały grudzień. Mamy nadzieję, że Ci się podobało.

Części kalendarza z adnotacjami i wizualnymi notatkami