Проектирование зданийдекабрь

Взгляд на процесс и инструменты, используемые для создания дизайна Designcember в стиле праздничного календаря.

В духе декабря и множества календарей, которые люди используют для обратного отсчета и празднования, мы хотели выделить веб-контент от сообщества и команды Chrome. Каждый день мы выделяли один фрагмент контента, связанного с разработкой пользовательского интерфейса и дизайном, всего 31 момент, среди которых было 26 новых демонстрационных сайтов, инструментов, объявлений, подкастов, видео, статей и тематических исследований.

Подробную информацию можно найти на сайте designcember.com .

Сайт Designcember.

Обзор

Нашей целью было предоставить доступный, необычный, современный и отзывчивый веб-интерфейс, занимающий как можно меньше байтов. Мы хотели выделить новые адаптивные API, такие как контейнерные запросы, и включить прекрасный пример темного режима на веб-сайт, ориентированный на дизайн и насыщенный ресурсами. Для достижения этой цели мы сжимали файлы, предлагали несколько форматов, использовали инструменты сборки, оптимизированные для создания статических сайтов, предоставили новый полифил и многое другое.

Начиная с прихоти

Идея сайта-календаря Designcember заключалась в том, чтобы служить витриной для всей работы, которую мы хотели продемонстрировать в течение декабря, одновременно действуя как демонстрационный сайт. Мы решили построить адаптивный многоквартирный дом, который мог бы стать выше и уже или короче и шире, с окнами, которые менялись бы внутри рамы. Каждое окно представляло один день (и, следовательно, одну часть контента). Мы работали с иллюстратором Элис Ли , чтобы воплотить наше видение в жизнь.

Эскизы скелета страницы Designcember.

Алиса вдохновляла, делилась процессами и эскизами, которые были захватывающими даже в их ранних концепциях. Пока она работала над артом, мы занимались архитектурой. Первые обсуждения велись вокруг макропланировки, здания и его окон. Как окна будут адаптироваться к одному, двум или трем столбцам, когда станет доступно больше места в области просмотра? Как далеко они могут сжаться или растянуться? Каковы будут максимальные размеры здания? Насколько сместятся окна?

Вот предварительный просмотр адаптивного прототипа с использованием grid-auto-flow: dense , показывающий, как окна могут автоматически размещаться с помощью алгоритма сетки. Мы быстро поняли, что, хотя сетки с соотношением сторон прекрасно подходят для демонстрации искусства, они не дают возможности позволить окнам расти и сжиматься в неоднородное доступное пространство и демонстрировать мощь контейнерных запросов.

Анимация, показывающая, как этот каркас реагирует на разные размеры экрана.
Посмотрите эту демонстрацию на CodePen.

Как только общая сетка стала относительно стабильной и давала представление о направлении реагирования здания и его окон, мы могли сосредоточиться на одном окне. Некоторые окна растягивались, сжимались, сжимались, росли и перестраивались сильнее, чем другие в сетке.

Каркасы, показывающие, как окна отображаются в различных точках останова.

Каждому окну придется обрабатывать определенное количество турбулентности при изменении размера. Ниже приведен прототип окна, демонстрирующий его реакцию на турбулентность и показывающий, насколько можно ожидать корректировки каждого интерактивного окна.

Анимация окон с помощью спрайт-таблиц

В некоторых окнах есть анимация, добавляющая интерактивности. Анимации рисуются вручную, кадр за кадром, в Photoshop. Каждый кадр экспортируется, превращается в спрайт-таблицу с помощью этого генератора спрайтов , а затем оптимизируется с помощью Squoosh. Затем CSS-анимация использует background-position-x и animation-timing-function , как показано в следующем примере.

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

Анимация, показывающая окно первого дня.

Некоторые анимации, такие как копилка шестого дня , представляли собой пошаговые CSS-анимации. Мы добились этого эффекта с помощью аналогичной техники, используя steps() , с той разницей, что ключевые кадры были позициями преобразования CSS, а не позициями фона.

CSS-маскировка

Некоторые окна имели уникальную форму. Мы использовали маски и aspect-ratio , чтобы создать масштабируемое, адаптивное окно уникальной формы.

Чтобы создать маску, подобную этой для восьмого окна, потребовались некоторые классические навыки Photoshop, а также немного знаний о том, как работают маски в Интернете. Давайте посмотрим на окно восьмого дня.

Окно восьмого дня.

Чтобы стать маской, внутреннюю форму типа четырехлистного клевера необходимо выделить как отдельную фигуру и залить белым цветом. Белый сообщает CSS, какой контент останется, а все, что находится за пределами белого, — нет. В Photoshop была выбрана внутренняя часть окна, растушевана на 1 пиксель (чтобы устранить проблемы с псевдонимами), затем залита белым и экспортирована с той же высотой и шириной, что и рамка окна. Таким образом, фрейм и маска могут быть наложены друг на друга, отображая внутреннее содержимое фрейма, как и ожидалось.

Изображение маски клевера

После завершения содержимое окна можно было изменить, и оно всегда будет оставаться в пределах пользовательского фрейма. На следующем изображении показана версия окна в темном режиме с другим градиентом фона и CSS-фильтром свечения, примененным к свету.

Окно восьмого дня в темном режиме.

Маскирование также поддерживает адаптивные окна на основе контейнерных запросов. В девятом окне есть персонаж, скрытый за маской, пока окно не станет более узким. Чтобы убедиться, что пользователь не сможет отрегулировать изображение за пределами кадра, Алиса доработала за нас полного персонажа. Персонаж замаскирован внутри окна, а растения — нет, поэтому еще одной проблемой, с которой мы столкнулись, было наложение замаскированных элементов на немаскированные слои и обеспечение хорошего масштабирования всех них вместе.

На следующем изображении показано, как это выглядит без маски на окне и персонажа.

Изображение девятого окна без маски.

Сдавливание искусства

Чтобы сохранить точность иллюстрации и гарантировать, что экраны высокой четкости не будут размытыми для пользователя, Алиса работала с соотношением пикселей 3x. Планировалось использовать imgix и размещать оптимизированные изображения и форматы на их сервере, но мы обнаружили, что ручная настройка с помощью инструмента Squoosh может сэкономить нам 50% и более.

Использование Squoosh для сжатия изображений.

У иллюстрации есть уникальные проблемы со сжатием, особенно с мазком кисти и прозрачным стилем с грубыми краями, который использовала Алиса. Мы решили сжать каждое трехкратное экспортированное в Photoshop изображение PNG до меньшего размера в формате PNG, WebP и avif. Каждый тип файлов имеет свои особые возможности сжатия, и потребовалось сжатие более 50 изображений, чтобы найти некоторые общие настройки оптимизации.

Интерфейс командной строки Squoosh стал решающим: для оптимизации потребовалось более 200 изображений — выполнение всех этих операций вручную заняло бы несколько дней. Получив общие настройки оптимизации, мы предоставили их в виде инструкций командной строки и пакетно обработали целые папки изображений PNG в их сжатые аналоги WebP и AVIF.

Вот пример использования команды 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

После того как оптимизированные изображения были добавлены в репозиторий, мы могли начать загружать их из 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>

Написание исходного кода изображений было утомительным, поэтому мы создали компонент Astro для встраивания изображений с помощью одной строки кода.

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

Пользователи программ чтения с экрана и клавиатуры

Большая часть опыта Designcember связана с искусством и интерактивными окнами. Для нас было важно, чтобы пользователь клавиатуры мог пользоваться сайтом и заглядывать в окна, а пользователи программ чтения с экрана получали приятный опыт повествования.

Например, при встраивании изображений мы использовали role="presentation" , чтобы пометить изображение как презентационное для программ чтения с экрана. Мы чувствовали, что использование от 5 до 12 разрозненных alt описаний будет плохим опытом. Итак, мы пометили изображения как презентационные и предоставили общее повествование в окне. Перемещение по окнам с помощью программы чтения с экрана создает приятное повествовательное ощущение, которое, как мы надеялись, поможет доставить удовольствие и причудливость, которыми сайт хочет поделиться.

В следующем видео показана демонстрация работы с клавиатурой. Клавиши Tab, Enter, пробел и escape используются для управления фокусом на всплывающих окнах и окнах и обратно.

Программа чтения с экрана имеет специальные атрибуты ARIA, которые вносят ясность в контент. Например, ссылки на дни содержат только «один» или «два», но с добавлением некоторых ARIA они объявляются как «День первый» и «День второй». Кроме того, все изображения объединены в одну метку, поэтому каждое окно имеет описание.

Astro, статический генератор сайтов на основе компонентов

Astro облегчила команде совместную работу на сайте. Модель компонентов была знакома разработчикам как Angular, так и React, а система стилей имен классов с ограниченной областью помогала каждому разработчику знать, что его работа над окном не будет конфликтовать с кем-либо еще.

Дни как компоненты

Каждый день представлял собой компонент , который получал статус из хранилища данных времени сборки . Это позволило нам запустить логику шаблона до того, как HTML достигнет браузера. Логика будет определять, должна ли день отображаться всплывающая подсказка или нет, поскольку у неактивных дней нет всплывающих окон.

Сборки запускаются каждый час, и хранилище данных времени сборки открывает новый день, когда сервер сборки перевалил за полночь. Эти самообновляющиеся и самодостаточные небольшие системы поддерживают сайт в актуальном состоянии.

Стили с ограниченной областью действия и открытые реквизиты

Стили астроскопов написаны внутри его компонентной модели , что упростило распределение рабочей нагрузки между многими членами команды, а также сделало использование Open Props увлекательным. Стили Open Propsnormalize.css пригодились с адаптивной (светлой и темной) темой, а также помогли разобраться с таким контентом, как абзацы и заголовки.

Будучи первыми, кто внедрил Astro, мы столкнулись с некоторыми трудностями при использовании PostCSS. Например, мы не смогли обновиться до последней версии Astro из-за слишком большого количества проблем со сборкой. Здесь можно было бы потратить больше времени, оптимизируя рабочие процессы сборки и разработки.

Гибкие контейнеры

Некоторые окна увеличиваются и уменьшаются, сохраняя соотношение сторон , чтобы сохранить свое искусство. Мы использовали несколько других окон, чтобы продемонстрировать возможности компонентной архитектуры с контейнерными запросами. Запросы к контейнеру означали, что окна могли владеть своей индивидуальной информацией об адаптивном стиле и корректироваться в зависимости от собственных размеров. Некоторые окна менялись с узких на широкие, и требовалось настроить размер медиафайлов внутри них, а также их размещение.

Демонстрация того, как меняются окна, когда у них становится больше места.

По мере того, как для окна становится больше места, мы можем адаптировать размер или дочерние элементы окна по размеру. Оказалось, что для реализации адаптивных окон контейнерные запросы было бы не просто интересно демонстрировать, они были бы необходимы и значительно упрощали бы оркестрацию определенных макетов.

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

Этот подход отличается от поддержания соотношения сторон. Он предлагает больше контроля и больше возможностей. При достижении определенного размера многие дети перемещаются, чтобы адаптироваться к новому расположению.

Контейнерные запросы также позволили нам поддерживать блочное (вертикальное) сдерживание, поэтому по мере увеличения длины окна мы могли корректировать его стили, чтобы они подходили подходящим образом. Это видно по запросам на основе высоты, которые мы использовали отдельно, а также в дополнение к запросам на основе ширины:

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

Мы также использовали контейнерные запросы, чтобы показывать и скрывать детали, поскольку при меньших размерах искусство становилось все более перегруженным, а при больших размерах — пустым. Девятое окно — отличный пример того, как это вошло в игру:

Кроссбраузерная поддержка

Чтобы создать отличный современный кроссбраузерный интерфейс, особенно для экспериментальных API, таких как контейнерные запросы, нам нужен отличный полифил. Мы обратились к нашей команде, и Сурма возглавил сборку нового полифила запроса контейнера . Полифил опирается на ResizeObserver , MutationObserver и функцию CSS:is() . Таким образом, все современные браузеры поддерживают полифилл, в частности Chrome и Edge с версии 88, Firefox с версии 78 и Safari с версии 14. Использование полифилла позволяет использовать любой из следующих синтаксисов:

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

Темный режим

Светлая и темная версии сайта Designcember рядом.

Последним штрихом, который был важен для веб-сайта Designcember, была красивая темная тема. Мы хотели показать, как вы можете использовать само искусство, чтобы стать активным участником создания великолепного темного режима. Для этого мы программно настроили стили фона каждого окна и использовали столько CSS, сколько имело смысл при создании оформления окна. Большинство фонов были градиентами CSS, чтобы было проще настраивать их цветовые значения. Затем мы наложили рисунок поверх них.

Другие пасхальные яйца

Персональные контакты

Мы добавили на страницу несколько индивидуальных штрихов, чтобы придать сайту больше индивидуальности. Первым был набор персонажей, вдохновленный нашей командой. Мы также включили курсор в стиле возврата в неактивные дни и поигрались со стилем значка.

Пользовательские стили курсора и параметры значков

Функциональные штрихи

Одним из дополнительных функциональных штрихов является функция «Перейти к сегодняшнему дню» с птицей, сидящей на вершине здания. Нажав на эту птичку или нажав Enter, вы перейдете на страницу вниз к текущему дню месяца, так что вы сможете быстро перейти к последним выпускам.

На Designcember.com также есть специальная таблица стилей печати, в которой мы, по сути, подаем конкретное изображение, которое лучше всего работает на бумаге размером 8,5 x 11 дюймов, чтобы вы могли распечатать календарь самостоятельно и оставаться праздничными в течение всего года.

Печать дизайна календаря в формате плаката.
Уна держит в руках большой отпечаток календаря.

В целом, тонна работы была потрачена на создание забавного, причудливого современного веб-интерфейса, посвященного разработке пользовательского интерфейса в течение всего декабря. Мы надеемся, что вам понравилось!

Части календаря с аннотациями и визуальными примечаниями