Designcember のホリデー カレンダー スタイルのエクスペリエンスを構築するために使用されたプロセスとツールをご紹介します。
12 月を記念して、多くのユーザーの皆様がカウントダウンやお祝いに使う多数のカレンダーに合わせて、コミュニティと Chrome チームからのウェブ コンテンツを紹介したいと考えました。UI 開発とデザイン関連のコンテンツを毎日紹介し、合計 31 のハイライトを取り上げました。その中には、26 の新しいデモサイト、ツール、お知らせ、ポッドキャスト、動画、記事、ケーススタディが含まれています。
詳しくは、designcember.com をご覧ください。
概要
私たちの目標は、アクセスしやすく、風変わりで、モダンで、レスポンシブなウェブ エクスペリエンスを、可能な限り少ないバイトで提供することでした。コンテナクエリなどの新しいレスポンシブ API を紹介し、デザイン重視でアセット中心のウェブサイトにダークモードの美しい例を含めたいと考えました。これを実現するために、ファイルの圧縮、複数の形式の提供、静的サイト生成用に最適化されたビルドツールの使用、新しいポリフィルの出荷などを行いました。
気まぐれなことから始める
Designcember カレンダー サイトのアイデアは、デモサイトのように機能しながら、12 月を通して私たちが注目したかったすべての作品を紹介するショーケースとして機能することでした。私たちは、縦に長く幅を狭くしたり、幅を狭くしたり幅広めしたりでき、窓がフレーム内で自動的に配置されるレスポンシブな集合住宅を作ることにしました。各ウィンドウは 1 日(つまり 1 つのコンテンツ)を表します。Google はイラストレーターの Alice Lee と協力して、ビジョンを形にしました。
Alice は刺激的で、初期のコンセプトでもエキサイティングなプロセスやスケッチを共有していました。アートの制作に携わる一方で、建築のハッキングも行いました。初期の議論では、マクロのレイアウト、建物、ウィンドウについて議論が行われました。ビューポートのスペースが増えると、ウィンドウは 1 列、2 列、または 3 列にどのように適応しますか。どのくらいまで縮小または伸ばせるでしょうか?建物の最大サイズはどれくらいですか。ウィンドウはどの程度移動しますか。
以下の grid-auto-flow: dense
を使用したレスポンシブ プロトタイプのプレビューは、グリッド アルゴリズムによってウィンドウがどのように自動配置されるかを示しています。私たちはすぐに、アスペクト比のグリッドはアートを見せるのに見栄えが良いものの、それではウィンドウを拡大、縮小して利用可能な不均一なスペースに収め、コンテナクエリの力を発揮する機会を持たないことにすぐに気づきました。
一般的なグリッドが比較的安定し、建物とその窓の応答性に関する方向感が伝われば、1 つのウィンドウに集中できます。一部の窓は、グリッド内の他の窓よりも引き伸ばされ、縮み、縮み、大きくなり、再構成されていました。
各ウィンドウは、サイズ変更の一定量のタービュランスを処理する必要があります。以下は、乱気流に対する反応性を示すウィンドウのプロトタイプです。各インタラクティブ ウィンドウの調整の程度が示されています。
スプライトシートを使用したウィンドウ アニメーション
一部のウィンドウには、エクスペリエンスに追加のインタラクションをもたらすアニメーションが表示されます。アニメーションは、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%; }
}
6 日目のブタの貯金箱などの一部のアニメーションは、ステップベースの CSS アニメーションでした。この効果は、steps()
を使用して同様の手法で実現しました。ただし、キーフレームが背景位置ではなく CSS 変換位置であった点が異なります。
CSS マスキング
一部の窓は独特の形状だった。マスクと aspect-ratio
を使用して、スケーラブルで独自の形状を持つアダプティブ ウィンドウを作成しました。
たとえばこのウィンドウ 8 のマスクを作成するには、Photoshop の従来のスキルと、ウェブ上のマスクの仕組みに関する少しの知識が必要でした。8 日目のウィンドウを見てみましょう。
マスクにするには、内側の四つ葉のクローバー タイプの形状を単独の形状として分離し、白で塗りつぶす必要があります。白はどのコンテンツを残すかを CSS に伝え、白以外のコンテンツは残しません。Photoshop ではウィンドウの内側を選択し、(エイリアシングの問題を取り除くために)1 ピクセルをフェージングした後、白で塗りつぶし、ウィンドウ フレームと同じ高さと幅でエクスポートしました。このようにして、フレームとマスクを互いに直接重ねて、フレーム内の内部コンテンツを想定どおりに表示できます。
完了するとウィンドウのコンテンツは変更可能で、常にカスタム フレーム内に収まっているように見えます。次の画像は、ダークモード版のウィンドウを示しています。異なる背景グラデーションとグロー CSS フィルタがライトに適用されています。
マスキングは、レスポンシブなコンテナクエリベースのウィンドウもサポートします。ウィンドウ 9 には、キャラクターがマスクで隠れ、ウィンドウのサイズが小さくなります。ユーザーがフレーム外に画像を調整できないようにするために、Alice はキャラクター全体を完成しました。キャラクターはウィンドウ内でマスクされますが、植物はマスクされません。そのため、マスクされた要素とマスクされていないレイヤを重ねて、すべてが適切にスケーリングされるようにするという課題に対処しました。
次の画像は、マスクなしでウィンドウとキャラクターがどのように表示されるかを示しています。
芸術作品をスクワッシュする
イラストの忠実性を維持し、高解像度の画面によってユーザー エクスペリエンスがぼやけないように、Alice はピクセル比率を 3 倍にしました。imgix を使用して、最適化された画像やフォーマットをサーバー上で提供する計画でしたが、Squoosh ツールを使った手作業で微調整すれば 50% 以上節約できることがわかりました。
イラストには圧縮に関する独特な課題があり、特にブラシのストロークと透明で粗いエッジ スタイルの Alice が使用されています。Photoshop でエクスポートした 3x PNG 画像を、それぞれより小さい png、webp、avif に Squoosh することにしました。各ファイルタイプには独自の圧縮能力があり、一般的な最適化設定を見つけるために 50 枚以上の画像を圧縮する必要がありました。
Squoosh CLI は、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>
画像のソースコードの記述は反復的だったため、1 行のコードで画像を埋め込む Astro コンポーネントを作成しました。
<Pic filename="day1/inner-frame" role="presentation" />
スクリーン リーダーとキーボードのユーザー
Designcember のエクスペリエンスの多くは、アートとインタラクティブなウィンドウを通して行われます。Google にとって重要だったのは、キーボード ユーザーがサイトを使用してウィンドウを覗くことができ、スクリーン リーダーのユーザーに優れたナレーション エクスペリエンスを提供できることです。
たとえば、画像を埋め込む際には、role="presentation"
を使用して、スクリーン リーダー向けに画像をプレゼンテーション用としてマークしました。alt
の説明が 5 ~ 12 個に分かれていると、ユーザー エクスペリエンスが低下すると判断しました。そのため、画像をプレゼンテーション用としてマークし、ウィンドウ全体のナレーションを提供しました。スクリーン リーダーのウィンドウを行き来すると、ナラティブな感覚が生まれます。それによって、サイトが共有したい気まぐれで楽しい雰囲気をお届けできればと思っています。
次の動画では、キーボード操作のデモを紹介しています。Tab キー、Enter キー、スペースバー、Esc キーはすべて、ウィンドウのポップアップやウィンドウへのフォーカスと、ウィンドウからのフォーカスをオーケストレートするために使用されます。
スクリーン リーダーのエクスペリエンスには、コンテンツをわかりやすくする特別な ARIA 属性があります。たとえば、リンクには「1 日」または「2 日」しか表示されませんが、ARIA を追加すると「1 日目」と「2 日目」と読み上げられます。さらに、すべての画像が 1 つのラベルに要約されているため、各ウィンドウに説明が表示されます。
Astro、静的ファースト、コンポーネント駆動型サイト生成ツール
Astro のおかげで、サイトでの共同作業が容易になりました。このコンポーネント モデルは Angular と React のどちらのデベロッパーにもなじみのあるものでしたが、スコープ設定されたクラス名スタイル システムにより、各デベロッパーがウィンドウでの作業が他のデベロッパーと競合しないことが分かりました。
コンポーネントとしての日数
ビルド時のデータストアからステータスを取得する各日がコンポーネントでした。これにより、HTML がブラウザに到達する前にテンプレートのロジックを実行できるようになりました。無効な日にはポップアップがないため、その日にツールチップを表示するかどうかがロジックで決定されます。
ビルドは 1 時間ごとに実行され、ビルドサーバーが深夜 0 時を過ぎると、ビルド時のデータストアによって新しい日が開始されます。自動更新と自己負担の小さいシステムが、サイトを最新の状態に保ちます。
スコープのスタイルとオープン プロップ
Astro のコンポーネント モデル内で記述されたスタイルがスコープされるため、多数のチームメンバー間での作業負荷の分散が容易になり、Open Props も楽しく利用できるようになりました。Open Props normalize.css スタイルは、アダプティブ(ライトモードとダークモード)テーマで便利で、段落やヘッダーなどのコンテンツをラングリングする際にも便利です。
Astro をいち早く採用していた当社は、PostCSS でいくつかの問題にぶつかりました。たとえば、ビルドの問題が多すぎるため、Astro の最新バージョンに更新できませんでした。ビルドとデベロッパーのワークフローの最適化に、より多くの時間を費やす可能性があります。
柔軟なコンテナ
一部のウィンドウは、アートを維持するためにアスペクト比を維持しながら拡大または縮小します。別のウィンドウで、コンテナクエリを使用したコンポーネント ベースのアーキテクチャの強みを紹介しました。コンテナクエリでは、ウィンドウが個別のレスポンシブ スタイル情報を所有し、独自のサイズに基づいて再調整できます。一部のウィンドウは横幅が広くなるため、その中のメディアのサイズやメディアの配置を調整する必要がありました。
1 つのウィンドウが使えるスペースが増えたら、それに合わせてウィンドウのサイズや子要素を調整できます。その結果、コンテナクエリは、表示するのも楽しいだけでなく、特定のレイアウトのオーケストレーションを大幅に簡素化する必要があることが判明しました。
.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);
}
}
また、アートが小さなサイズでは見づらくなり、より広いサイズではより表示されるようになったため、コンテナクエリを使用して詳細の表示 / 非表示を切り替えました。ウィンドウ 9 は、このことが影響を及ぼした好例です。
クロスブラウザ サポート
最新のクロスブラウザ エクスペリエンスを向上させるには、特にコンテナクエリなどの試験運用版 API で、優れたポリフィルが必要です。私たちのチームに呼びかけたところ、Surma は新しいコンテナクエリ ポリフィルのビルドの指揮を執りました。ポリフィルは、ResizeObserver、MutationObserver、CSS の :is() 関数に依存します。そのため、最新のブラウザはすべてポリフィルをサポートしています。具体的には、Chrome と Edgefrom バージョン 88、Firefox バージョン 78、Safari バージョン 14 です。ポリフィルを使用すると、次のいずれかの構文を使用できます。
/* These are all equivalent */
@container (min-width: 200px) {
/* ... */
}
@container (width >= 200px) {
/* ... */
}
@container size(width >= 200px) {
/* ... */
}
ダークモード
最後に、Designcember ウェブサイトに不可欠な要素は、美しいダークモードです。優れたダークモードの作成に積極的に参加するために、アート自体をどのように活用できるかをご紹介しました。そのために、各ウィンドウ自体の背景スタイルをプログラムで調整し、ウィンドウ アートを作成する際に適切な CSS を使用しました。背景のほとんどは CSS グラデーションだったため、色値の調整は簡単になりました。その上にアートを重ねました。
その他のイースター エッグ
パーソナルな接触
ページにいくつかの個性を加えて、サイトに個性を与えています。1 つ目は、当チームからインスピレーションを得たキャラクターのキャストでした。また、利用されていない日には懐かしいスタイルのカーソルを追加し、ファビコン スタイルを試しました。
機能面
その他の機能面では、建物の上に鳥がいる「今日へ移動」機能が挙げられます。この鳥の上でクリックするか Enter キーを押すと、その月の現在の日付にジャンプするため、最新のリリースにすばやくアクセスできます。
Designcember.com には、特別な印刷スタイルシートも用意されており、基本的には 8.5 x 11 インチの用紙に最適な特定の画像を提供しているため、自分でカレンダーを印刷して 1 年中お祝いできます。
全体として、12 月の UI 開発を祝うために、楽しくて風変わりなモダンなウェブ エクスペリエンスの制作には多くの取り組みが行われました。お楽しみいただけたでしょうか。