【ITニュース解説】The Impossible Filter Gallery Transition in CSS Only
2026年09月23日に「Dev.to」が公開したITニュース「The Impossible Filter Gallery Transition in CSS Only」について初心者にもわかりやすく解説しています。
ITニュース概要
JavaScriptを使わずCSSだけで動くフィルターギャラリー遷移の実現方法を解説。カスタムCSS変数と`:has()`疑似クラスを駆使し、画像の初期配置、クリック時の移動、レスポンシブ表示を制御。CSSのみで複雑なUIインタラクションを構築する革新的なテクニックだ。
ITニュース解説
このニュース記事は、ウェブサイト上でよく見かける「フィルターギャラリー」という機能を、通常使われるJavaScriptというプログラミング言語を使わず、CSS(Cascading Style Sheets)のみで実現する方法について解説している。システムエンジニアを目指す初心者にとって、ウェブの見た目や動きを作るCSSが、どれほど進化し、高度な表現力を持ち始めているかを知る良い機会となるだろう。
フィルターギャラリーとは、複数の写真や情報を一覧で表示し、「自然」「動物」「人物」といった分類(カテゴリ)ボタンをクリックすることで、選択したカテゴリに属するアイテムだけが表示され、他のアイテムは非表示になる仕組みのことである。一般的に、このようなユーザーの操作(ボタンのクリックなど)に応じて表示内容を動的に変化させるには、JavaScriptを使ってプログラムを記述するのが一般的だ。しかし、この記事の筆者は「CSSのセレクタ(HTML要素を指定するための規則)だけで、どこまで実現できるか」という実験を行い、その驚くべき結果を紹介している。
このCSSのみでのフィルターギャラリー実現の鍵となっているのは、主に二つのCSSの強力な機能である。一つは「カスタム変数(CSS Variables)」、もう一つは「:has()擬似クラス」という比較的新しいセレクタだ。
まずカスタム変数について説明しよう。これはCSSの中で自分で好きな名前を付けて値を定義できる機能で、たとえば--primary-color: #3498db;のように定義し、後でcolor: var(--primary-color);のようにその値を再利用できる。これにより、ウェブサイト全体のデザインで共通する色やサイズなどを一元的に管理でき、変更が必要な際も一箇所の修正で済むようになる。この記事では、各写真カードの初期配置や、フィルター適用後に移動する位置を細かく制御するために、--l(横方向の初期位置インデックス)、--t(縦方向の初期位置インデックス)、--x(横方向の移動後位置インデックス)、--y(縦方向の移動後位置インデックス)といったカスタム変数を各HTML要素のstyle属性に直接設定している。この「ハードコードされたカスタム変数」の使い方が、フィルターギャラリーの動きをCSSだけで制御する独創的な方法となっている。
HTMLの構造は、まずカテゴリを選択するためのラジオボタン(input type="radio")が並んでおり、それぞれのラジオボタンにはid="all", id="nature"などが設定されている。これらのidは、後述する:has()擬似クラスと連携し、どのカテゴリが選択されているかをCSSが判断するために非常に重要だ。その下には、実際に写真カードが並ぶul要素があり、その中に個々の写真を表すli要素が多数配置されている。各li要素には、どのカテゴリに属するかを示すクラス名(例: class="category nature")と、上述のカスタム変数がstyle属性を通じて指定されている。
これらのカスタム変数は、CSSのcalc()関数と組み合わせて、カードの具体的な配置位置を計算するために使われる。たとえば、left: calc(var(--l) * var(--w) * 1px);という記述では、カードの幅を示す--wという変数と、そのカードの横方向のインデックスを示す--lという変数を掛け合わせることで、カードが左端からどれだけ離れて配置されるかを動的に計算している。これにより、--lが0のカードは一番左に、--lが1のカードはその右に、といった具合に、カードが整然とグリッド状に並べられる。縦方向の位置(top)も同様に、--t変数とカードの高さを示す--h変数を使って計算される。
この技術の肝となるフィルタリングのロジックは、:has()擬似クラスという、ある要素が特定の条件を満たす子孫要素を持っている場合に、その要素自身にスタイルを適用できるセレクタによって実現されている。例えば、body:has(#all:checked) liというCSSルールは、「ページ全体(body)の中にidがallのラジオボタンがチェックされている状態であれば、そのページ内のすべてのli要素にスタイルを適用する」という意味になる。
具体的には、Allボタンが選択されている場合、すべてのli要素は初期配置を示す--lと--t変数で指定された位置に配置される。一方、例えばNatureボタンが選択された場合、body:has(#nature:checked) .natureというルールが適用され、natureクラスを持つカードは、フィルター適用後の新しい配置を示す--xと--y変数で指定された位置に移動する。同時に、選択されていないカテゴリのカード(例えば、Natureが選択されているときにAnimalsカテゴリのカード)は、opacity: 0; scale: 0; width: 0; height: 0;といったスタイルが適用され、透明化、縮小、そして最終的には画面上から見えなくなる。これらの位置や見た目の変化は、transition: 0.5s all ease;という指定により、0.5秒という時間を使って滑らかにアニメーションしながら行われるため、ユーザーは自然で心地よい動きを体験できる。
この実装は、異なる画面サイズに対応する「レスポンシブデザイン」にも配慮されている。@media (max-width: 760px)のようなCSSのメディアクエリを使うことで、画面の幅が狭くなった場合に適用されるスタイルを定義している。特に注目すべきは、レスポンシブ対応のために、初期配置用の--l1, --t1と、クリック後の移動位置用の--x1, --y1といった別のカスタム変数が用意されている点だ。これにより、デスクトップ表示とモバイル表示とで、カードの並び順やフィルター適用後の配置を柔軟に調整できるようになっている。記事では、さらに多くの画面サイズに対応が必要な場合に、さらに多くのカスタム変数を追加するアプローチも提案されており、カスタム変数がレイアウト調整に非常に有効な手段であることが示されている。
さらに、このコードには、画像をクリックすると拡大表示される「ライトボックス」機能もCSSのみで実装されている。これは、画像要素がフォーカスされた状態(img:focus)をCSSが検知してスタイルを適用することで実現している。HTMLの画像要素にはtabindex="0"という属性が設定されており、これによりキーボード操作やクリックでフォーカスできるようになっている。画像がクリックされフォーカスされると、背景に半透明の黒いオーバーレイが表示され、クリックされた画像自体は画面の中央で大きく表示される。この拡大表示も、@keyframesで定義されたアニメーションによって滑らかに変化する。また、拡大された画像の下にはキャプションが表示されるようにも設定されており、これもアニメーションして現れる。これらすべてが、JavaScriptを一切使わず、CSSのセレクタとアニメーション機能だけで実現されているのは、CSSの進化と可能性を強く感じさせる部分である。
この記事で紹介されている技術は、CSSの最新機能である:has()擬似クラスとカスタム変数を最大限に活用し、これまでJavaScriptが必須とされてきた高度なインタラクションをCSSのみで実現する可能性を示している。一部に手作業での値設定(ハードコーディング)が多く残るという課題はあるものの、CSSだけでこれほど動的な挙動を作り出す工夫は、フロントエンド開発の新しいアプローチとして非常に参考になる。この実験は、CSSの進化によって、開発者がより少ないツールでリッチなユーザーインターフェースを構築できるようになる未来を垣間見せてくれるものだ。