コハム

Webクリエイターのコハムが提供する、Web制作に役立つ情報をまとめたブログです。

目からウロコ!CSSグリッドで作る魔法のアニメーション画像ギャラリー

How to animate CSS Grid layouts (image grid project)

記事は上記記事を意訳したものです。

※当ブログでの翻訳記事は元サイト様に許可を得て掲載しています。


CSSグリッドのプロパティの一部をアニメーション化できることが判明しました!今日は、ホバーエフェクトを持つレスポンシブな画像グリッドを構築することで、この動作を実際に見ていきます。この機会に、強力な :has() CSSセレクタも活用します。

始めましょう!

画像グリッド

以下が作成するものです—大画面(≥900px)でフルスクリーンデモを表示し、カードにホバーしてください:

1. マークアップ

コンテナ内に6つのカードを配置することから始めます。最初の3つと最後の2つを入れ子のコンテナ内にラップします。以下のマークアップをご覧ください:

<div class="grid">
  <div class="sub-grid sub-grid-1">
    <article class="card">...</article>
    <article class="card">...</article>
    <article class="card">...</article>
  </div>
  <article class="card">...</article>
  <div class="sub-grid sub-grid-2">
    <article class="card">...</article>
    <article class="card">...</article>
  </div>
</div>

各カードは以下の構造を持ちます:

<article class="card">
  <figure>
    <img width="IMG_WIDTH" height="IMG_HEIGHT" src="IMG_URL" alt="">
    <figcaption>
      <div>
        ...
        <span>
          by <a href="UNSPLASH_URL" target="_blank">...</a>
        </span>
      </div>
    </figcaption>
  </figure>
</article>

2. スタイル

小さな画面(<900px)では、すべてのカードが積み重ねられ、その情報が表示されます。

大きな画面では、3列のレイアウトになります。

ここでは、ホバーメディアクエリの助けを借りて、2つのシナリオをチェックします:

  1. ホバーをサポートしていないデバイスからページを見る場合、ギャラリーは次のようになります。

  1. デスクトップブラウザまたはホバーを持つデバイスからページを見る場合、ギャラリーレイアウトは次のように変更されます:

この場合、すべてのカードをグレースケールにし、詳細を非表示にします。ユーザーがカードにホバーすると、サイズを大きくして情報を表示します。詳細は後ほど説明します。

3列レイアウト

3列レイアウトについてもう少し詳しく説明しましょう。

[3列レイアウトの画像]

  • CSSグリッドを使用してセットアップします。
  • 最初の列は他の2つの2倍のサイズになります。
  • 最初の列の中には、3番目の列が他の2つの2倍のサイズで、それらの下に配置される入れ子のグリッドがあります。行の高さは40vhで、--half-height CSS変数を通じてカスタマイズ可能です。
  • 最初の列の高さは他の2つの2倍(80vh)になります。これも --height CSS変数を通じてカスタマイズできます。
  • 3番目の列の中には、列が積み重ねられ、行の高さも40vhの入れ子のグリッドがあります。

関連するスタイルは以下の通りです:

:root {
  --height: 80vh;
  --half-height: calc(var(--height) / 2);
}

@media (min-width: 900px) {
  .grid,
  .sub-grid {
    display: grid;
  }
  .grid {
    grid-template-columns: 2fr 1fr 1fr;
  }
  .sub-grid {
    grid-template-rows: var(--half-height) var(--half-height);
  }
  .sub-grid-1 {
    grid-template-columns: 1fr 1fr auto;
  }
  .sub-grid-1 .card:last-child {
    grid-column: 1/-1;
  }
  /*.sub-grid-2 { 
    grid-template-columns: 1fr; 
  }*/
}

ホバーエフェクト

カード/列にホバーするたびに、幅または高さを拡大してズーム効果を生み出します。CSSグリッドを使用してレイアウトを構築したため、ホバー時に grid-template-rowsgrid-template-columns プロパティの値を更新する必要があります。

ただし、これらのプロパティはカード自体ではなく、先祖要素に設定されています。通常であれば、JavaScriptを使用して更新しますが、幸いなことに、:has() 関係セレクタを使用すればこれが可能になります。

アニメーション #1

このセレクタの動作を見てみましょう。

グリッドの2番目の列を考えてみます。

最初は、次のルールがあります:

.grid {
  grid-template-columns: 2fr 1fr 1fr;
  transition: all 1s;
}

そのカードにホバーすると、グリッド幅全体を覆うように拡大します。

[ホバー時の2番目の列の画像]

魔法を行うCSSルールは次のとおりです:

.grid:has(> .card:hover) {
  grid-template-columns: 0fr 1fr 0fr;
}

上記のルールは、直接のグリッド列がホバーされているかどうかをチェックします。その条件が満たされると、grid-template-columns プロパティの値を更新して、最初と3番目の列を非表示にし、1番目の列がそのスペースを占めるように拡大します。

注意:アニメーションを機能させるには、0ではなく0frを使用してください!

アニメーション #2

もう一つの例を見てみましょう。

最初の列の最初の入れ子列を考えてみます。

[最初の列の最初の入れ子列の画像]

最初は、次のルールがあります:

.sub-grid-1 {
  grid-template-columns: 1fr 1fr auto;
  transition: all 1s;
}

そのカードにホバーすると、サイズが2倍になり、2番目のカードが非表示になります:

[ホバー時の最初の列の最初の入れ子列の画像] 魔法を行うCSSルールは次のとおりです:

.grid:has(.sub-grid-1 .card:first-of-type:hover) .sub-grid-1 {
  grid-template-columns: 1fr 0fr auto;
}

上記のルールは、最初のグリッド列(グリッドコンテナとして機能する)の最初の入れ子列がホバーされているかどうかをチェックします。その条件が満たされると、grid-template-columns プロパティの値を更新して、2番目の入れ子列を非表示にし、1番目の列がそのスペースを占めるように拡大します。

注意:アニメーションを機能させるには、0ではなく0frを使用してください!

アニメーション #3

最後にもう一つの例を見てみましょう。

3番目の列の最初の入れ子列を考えてみます。

[3番目の列の最初の入れ子列の画像]

最初は、次のルールがあります:

.sub-grid-2 {
  grid-template-rows: 40vh 40vh;
  transition: all 1s;
}

そのカードにホバーすると、高さが2倍になり、2番目のカードが非表示になります:

[ホバー時の3番目の列の最初の入れ子列の画像]

魔法を行うCSSルールは次のとおりです:

.grid:has(.sub-grid-2 .card:first-of-type:hover) .sub-grid-2 {
  grid-template-rows: 80vh 0;
}

上記のルールは、3番目のグリッド列(グリッドコンテナとして機能する)の最初の入れ子列がホバーされているかどうかをチェックします。その条件が満たされると、grid-template-rows プロパティの値を更新して、2番目の入れ子列を非表示にし、1番目の列が垂直方向に拡大してそのスペースを占めるようにします。

カードのスタイルについては、CSSネスティングを使用しています。デモのCSSタブをクリックすると、残りのスタイルを確認できます。

結論

完成です!このチュートリアルでは、強力な :has() CSS擬似クラスの助けを借りて、CSSグリッドレイアウトをアニメーション化する方法を学びました。このプロジェクトを楽しみ、新しい知識を得られたことを願っています。

改めて、今日作成したものは次の通りです:

いつものように、お読みいただきありがとうございました!

©コハム