Pure CSS Gallery Focus Effect a :not funkcióval

Forrás csomópont: 1723238

A múltban gyakran kellett kitalálnom, hogyan adhatok stílusokat a tárolón belüli összes elemhez, de nem a lebegett.

A testvérekre gyakorolt ​​várható „elhalványulási” hatás bemutatója, amely lehetővé teszi a felhasználók számára, hogy egy adott elemre „fókuszáljanak”.

Ehhez az effektushoz ki kell választani egy lebegtetett elem testvéreit. Ehhez JavaScriptet használtam, hozzáadva vagy eltávolítva azt az osztályt, amely meghatározta a megfelelő CSS-szabályokat mouseenter és a mouseleave ehhez hasonló események:

Bár a kód megteszi a trükköt, a megérzésem mindig azt súgta, hogy léteznie kell valamilyen tiszta CSS-módszernek ugyanazon eredmény elérésére. Néhány évvel ezelőtt, miközben egy bizonyos csúszkán dolgoztam a cégem számára, egy ehhez hasonló megoldásra jutottam hogyan készítette el Chris Geelhoed a híres Netflix kezdőlap-animációt és megértettem, hogy ehhez már nincs szükségem JavaScriptre.

Néhány hónappal ezelőtt ugyanezt a megközelítést próbáltam megvalósítani egy rács alapú hírfolyamban a cégem webhelyén, és – bumm – az elemek közötti rés miatt nem működött!

Szerencsémre úgy tűnt, hogy ennek nem kell így maradnia, és megint nem kellett hozzá JavaScript.

Jelölés és alap CSS

Kezdjük a kódolást a megfelelő jelölés elkészítésével:

  • .grid rács alapú

      lista;

    • és a .grid__child elemek azok
    • gyerekek, akikkel kommunikálni szeretnénk.

    A jelölés így néz ki:

    A stílusnak így kell kinéznie:

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

    Ez a példakód három listaelemet hoz létre, amelyek három oszlopot foglalnak el egy rácsban.

    A CSS-szelektorok ereje

    Most pedig adjunk hozzá némi interaktivitást. Az általam eredetileg alkalmazott megközelítés két lépésen alapult:

    1. a konténeren lebegve az összes elem stílusát meg kell változtatnia...  
    2. …kivéve azt, amelyiken a kurzor éppen lebeg.

    Kezdjük azzal, hogy minden gyermeket megragadunk, miközben a kurzor a tároló felett lebeg:

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

    Másodszor, zárjuk ki az aktuálisan lebegő elemet, és csökkentsük a opacity bármely más gyermekről:

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

    És ez tökéletesen elegendő lenne olyan konténerekhez, amelyekben nincsenek hézagok a gyermekelemek között:

    Animált GIF egy egérkurzorról, amely kölcsönhatásba lép olyan elemekkel, amelyeket nem választ el semmilyen hézag.
    Egy olyan megoldás bemutatója, amely hiányosságok nélkül működik.

    Az én esetemben azonban nem tudtam eltávolítani ezeket a hiányosságokat:

    Animált GIF egy egérkurzorral az elemek felett. Ha azonban az egér bejut egy résbe két elem között, a hatás akkor ér véget, amikor az egér elhagyja az elemet.
    A hiányosságok bevezetésekor tapasztalt probléma bemutatója.

    Amikor az egeret mozgattam a csempék között, az összes gyerekelem elhalványult.

    A hiányosságok figyelmen kívül hagyása

    Feltételezhetjük, hogy a rések a tartály olyan részei, amelyeket nem takarnak el a gyermekei. Nem akarjuk minden alkalommal futtatni az effektust, amikor a kurzor belép a tárolóba, hanem akkor, amikor az egyik elem fölé viszi az egeret. Figyelmen kívül hagyhatjuk a rések felett mozgó kurzort? 

    Igen, használhatjuk pointer-events: none a .grid konténerben, és visszahozza őket pointer-events: auto gyermekeire:

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

    Adjunk hozzá egy jó átmenetet az átlátszatlansághoz, és máris készen áll a komponens:

    Valószínűleg még menőbb, ha több csempét adunk hozzá, és létrehozunk egy kétdimenziós elrendezést:

    A végső CSS így néz ki:

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

    Mindössze 2 további kódsorral megoldottuk a hiányosságot!

    Lehetséges problémák

    Bár kompakt megoldásról van szó, vannak olyan helyzetek, amikor szükség lehet valamilyen megkerülő megoldásra.

    Sajnos ez a trükk nem működik, ha azt szeretné, hogy a tároló görgethető legyen, például valami vízszintes csúszkában. A pointer-events: none a stílus nem csak a lebegés eseményt hagyná figyelmen kívül, hanem az összes többit is. Ilyen helyzetekben becsomagolhatja a .grid egy másik tárolóban, például:

    Összegzésként

    Nyomatékosan ajánlom, hogy kísérletezzen, és próbáljon egyszerűbb és natívabb megközelítést találni azokhoz a feladatokhoz, amelyek általában bizonyos szintű bonyolultságot igényelnek. A webes technológiák, mint például a CSS, egyre erősebbek, és az azonnali natív megoldások használatával nagyszerű eredményeket érhet el anélkül, hogy karban kellene tartania a kódját és át kellene adnia azt a böngésző gyártóinak.

    Remélem tetszett ez a rövid bemutató, és hasznosnak találtad. Kösz!

    A szerző kiválasztotta a Tech Oktatás részeként adományt kapni Írjon adományokért program.

    Időbélyeg:

    Még több CSS trükkök