:not を使用した純粋な CSS ギャラリー フォーカス効果

ソースノード: 1723238

以前は、コンテナ内のすべての要素にスタイルを追加する方法を理解する必要がありましたが、 ホバリングしたもの。

ユーザーが特定の要素に「集中」できるように、兄弟に期待される「フェードアウト」効果のデモ。

この効果では、ホバーされた要素の兄弟を選択する必要があります。 これには JavaScript を適用し、適切な CSS ルールを定義したクラスを追加または削除していました。 mouseenter & mouseleave 次のようなイベント:

コードはうまく機能しますが、同じ結果を得るには純粋な CSS の方法が必要であるという直感が常にありました。 数年前、会社の特定のスライダーに取り組んでいるときに、次のような解決策を思いつきました Chris Geelhoed が有名な Netflix ホームページ アニメーションをどのように再現したか そして、これにはもう JavaScript は必要ないことを理解しました。

数か月前、私は自分の会社の Web サイトでグリッドベースのフィードに同じアプローチを実装しようとしましたが、要素間のギャップが原因で機能しませんでした。

幸いなことに、このままにしておく必要はないように見えたので、ここでも JavaScript は必要ありませんでした。

マークアップとベース CSS

適切なマークアップを準備してコーディングを始めましょう。

  • .grid グリッドベースです

      リスト。

    • & .grid__child 要素は
    • 触れ合いたい子どもたち。

    マークアップは次のようになります。

    スタイルは次のようになります。

    .grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, 15rem);
      grid-gap: 1rem;
    }
    
    .grid__child {
      background: rgba(0, 0, 0, .1);
      border-radius: .5rem;
      aspect-ratio: 1/1;
    }

    このサンプル コードは、グリッド内の XNUMX つの列を占める XNUMX つのリスト アイテムを作成します。

    CSS セレクターの威力

    では、インタラクティブ機能を追加しましょう。 私が最初に適用したアプローチは、次の XNUMX つのステップに基づいていました。

    1. コンテナにカーソルを合わせると、内部のすべての要素のスタイルが変更されるはずです…  
    2. …現在カーソルがホバリングしているものを除きます。

    カーソルがコンテナーの上にある間に、すべての子を取得することから始めましょう。

    .grid:hover .grid__child {
      /* ... */
    }

    次に、現在ホバリングされているアイテムを除外して、 opacity 他の子供の場合:

    .grid:hover .grid__child:not(:hover) {
      opacity: 0.3;
    }

    これは、子要素間にギャップのないコンテナーには完全に十分です。

    ギャップで区切られていない要素と相互作用するマウス カーソルのアニメーション GIF。
    隙間なく機能するソリューションのデモ。

    ただし、私の場合、これらのギャップを取り除くことができませんでした:

    要素の上に置かれたマウス カーソルのアニメーション GIF。 ただし、マウスが XNUMX つの要素の間のギャップに入ると、マウスが要素から離れると効果が終了します。
    ギャップが導入されたときに発生する問題のデモ。

    タイル間でマウスを動かしていると、すべての子要素がフェードアウトしていました。

    ギャップを無視する

    ギャップは、その子によってオーバーレイされていないコンテナの一部であると想定できます。 カーソルがコンテナーに入るたびにエフェクトを実行するのではなく、コンテナー内の要素の XNUMX つにカーソルを置いたときに実行します。 ギャップの上を移動するカーソルを無視できますか? 

    はい、使用できます pointer-events: none .grid コンテナとそれらを持ち帰る pointer-events: auto その子について:

    .grid {
      /* ... */
      pointer-events: none;
    }
    
    /* ... */
    
    .grid__child {
      /* ... */
      pointer-events: auto;
    }

    opacity にクールなトランジションを追加して、準備完了のコンポーネントを用意しましょう。

    さらにタイルを追加して 2 次元のレイアウトを作成すると、おそらくさらにクールになります。

    最終的な CSS は次のようになります。

    .grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, 15rem);
      grid-gap: 3rem;
      pointer-events: none;
    }
    
    .grid:hover .grid__child:not(:hover) {
      opacity: 0.3;
    }
    
    .grid__child {
      background: rgba(0, 0, 0, .1);
      border-radius: .5rem;
      aspect-ratio: 1/1;
      pointer-events: auto;
      transition: opacity 300ms;
    }

    コードを 2 行追加するだけで、ギャップの問題を克服できました。

    考えられる問題

    これはコンパクトなソリューションですが、いくつかの回避策が必要になる場合があります。

    残念ながら、このトリックは、コンテナをスクロール可能にしたい場合には機能しません。たとえば、ある種の水平スライダーなどです。 の pointer-events: none style は hover イベントだけでなく、他のすべてのイベントも無視します。 このような状況では、ラップすることができます .grid 次のように、別のコンテナーに入れます。

    まとめ

    通常はある程度の複雑さが予想されるタスクに対して、よりシンプルでネイティブなアプローチを試してみることを強くお勧めします。 CSS などの Web テクノロジはますます強力になり、すぐに使用できるネイティブ ソリューションを使用することで、コードを保守したり、ブラウザー ベンダーに譲渡したりする必要なく、優れた結果を得ることができます。

    この短いチュートリアルを気に入っていただき、お役に立てば幸いです。 ありがとう!

    作者が選んだのは テク 教育 の一環として寄付を受け取る 寄付のために書く プログラム。

    タイムスタンプ:

    より多くの CSSトリック