Ein reiner CSS-Galerie-Fokuseffekt mit :not

Quellknoten: 1723238

In der Vergangenheit musste ich oft herausfinden, wie ich Stile zu allen Elementen im Container hinzufügen kann, aber nicht der geschwebte.

Demo des erwarteten „Fade-out“-Effekts bei Geschwistern, damit Benutzer sich auf ein bestimmtes Element „fokussieren“ können.

Dieser Effekt erfordert die Auswahl der Geschwister eines schwebenden Elements. Früher habe ich dafür JavaScript angewendet und die Klasse hinzugefügt oder entfernt, die die richtigen CSS-Regeln definiert hat mouseenter und mouseleave Veranstaltungen, ähnlich wie diese:

Obwohl der Code es tut, sagte mir mein Bauchgefühl immer, dass es einen reinen CSS-Weg geben muss, um das gleiche Ergebnis zu erzielen. Als ich vor einigen Jahren an einem bestimmten Slider für mein Unternehmen arbeitete, kam ich auf eine ähnliche Lösung wie wie Chris Geelhoed die berühmte Netflix-Homepage-Animation nachgebaut hat und ich verstand, dass ich dafür kein JavaScript mehr brauchte.

Vor ein paar Monaten habe ich versucht, den gleichen Ansatz für einen rasterbasierten Feed auf meiner Unternehmenswebsite zu implementieren, und – boom – es hat wegen der Lücke zwischen den Elementen nicht funktioniert!

Zum Glück für mich hat sich herausgestellt, dass es nicht so bleiben muss, und wieder einmal brauchte ich kein JavaScript dafür.

Markup und Basis-CSS

Beginnen wir mit dem Codieren, indem wir das richtige Markup vorbereiten:

  • .grid ist rasterbasiert

      Liste;

    • und .grid__child Elemente sind
    • Kinder, mit denen wir interagieren möchten.

    Das Markup sieht so aus:

    Der Stil sollte so aussehen:

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

    Dieser Beispielcode erstellt drei Listenelemente, die drei Spalten in einem Raster belegen.

    Die Macht der CSS-Selektoren

    Lassen Sie uns nun etwas Interaktivität hinzufügen. Der Ansatz, den ich ursprünglich angewendet habe, basierte auf zwei Schritten:

    1. Wenn Sie den Mauszeiger über den Container bewegen, sollten sich die Stile aller Elemente darin ändern ...  
    2. …außer dem, über dem der Cursor gerade schwebt.

    Beginnen wir damit, jedes Kind zu greifen, während der Cursor über dem Container schwebt:

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

    Zweitens schließen wir das aktuell schwebende Element aus und reduzieren die opacity von jedem anderen Kind:

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

    Und das würde für Container ohne Lücken zwischen den untergeordneten Elementen vollkommen ausreichen:

    Animiertes GIF eines Mauszeigers, der mit Elementen interagiert, die nicht durch Lücken getrennt sind.
    Demo einer lückenlos funktionierenden Lösung.

    In meinem Fall konnte ich diese Lücken jedoch nicht entfernen:

    Animiertes GIF eines Mauszeigers, der über Elementen schwebt. Wenn die Maus jedoch in eine Lücke zwischen zwei Elementen eintritt, endet der Effekt, wenn die Maus das Element verlässt.
    Demo des Problems, das auftritt, wenn Lücken eingeführt werden.

    Als ich die Maus zwischen den Kacheln bewegte, wurden alle Kinderelemente ausgeblendet.

    Lücken ignorieren

    Wir können davon ausgehen, dass Lücken Teile des Containers sind, die nicht von seinen Kindern überlagert werden. Wir möchten den Effekt nicht jedes Mal ausführen, wenn der Cursor in den Container eintritt, sondern wenn er über eines der Elemente darin schwebt. Können wir den Cursor ignorieren, der sich über den Lücken bewegt? 

    Ja, wir können, mit pointer-events: none auf die .grid Behälter und bringen sie mit zurück pointer-events: auto auf seine Kinder:

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

    Fügen wir einfach einen coolen Übergang zur Deckkraft hinzu und wir haben eine fertige Komponente:

    Es ist wahrscheinlich noch cooler, wenn wir mehr Kacheln hinzufügen und ein zweidimensionales Layout erstellen:

    Das endgültige CSS sieht so aus:

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

    Mit nur 2 zusätzlichen Codezeilen haben wir das Lückenproblem überwunden!

    Mögliche Probleme

    Obwohl es sich um eine kompakte Lösung handelt, gibt es einige Situationen, in denen möglicherweise einige Problemumgehungen erforderlich sind.

    Leider funktioniert dieser Trick nicht, wenn Sie möchten, dass der Container scrollbar ist, zB wie bei einer Art horizontalem Schieberegler. Das pointer-events: none style würde nicht nur das Hover-Ereignis, sondern auch alle anderen ignorieren. In solchen Situationen können Sie die wickeln .grid in einem anderen Container, wie folgt:

    Zusammenfassung

    Ich ermutige Sie dringend, zu experimentieren und zu versuchen, einen einfacheren und nativeren Ansatz für Aufgaben zu finden, von denen normalerweise erwartet wird, dass sie ein gewisses Maß an Komplexität aufweisen. Webtechnologien wie CSS werden immer leistungsstärker und durch die Verwendung von sofort einsatzbereiten nativen Lösungen können Sie großartige Ergebnisse erzielen, ohne Ihren Code warten und an Browserhersteller abgeben zu müssen.

    Ich hoffe, dass Ihnen dieses kurze Tutorial gefallen hat und Sie es nützlich fanden. Vielen Dank!

    Der Autor hat die ausgewählt Technik Bildungswesen eine Spende im Rahmen der zu erhalten Schreiben Sie für Spenden 

    Zeitstempel:

    Mehr von CSS-Tricks