Ένα Pure CSS Gallery Focus Effect με :not

Κόμβος πηγής: 1723238

Πολλές φορές στο παρελθόν, χρειαζόταν να καταλάβω πώς να προσθέσω στυλ σε όλα τα στοιχεία μέσα στο κοντέινερ αλλά δεν το αιωρούμενο.

Επίδειξη του αναμενόμενου εφέ "εξαφανισμού" στα αδέρφια για να επιτρέψει στους χρήστες να "εστιάσουν" σε ένα συγκεκριμένο στοιχείο.

Αυτό το εφέ απαιτεί την επιλογή των αδελφών ενός στοιχείου που αιωρείται. Συνήθιζα να εφαρμόσω JavaScript για αυτό, προσθέτοντας ή αφαιρώντας την κλάση που καθόριζε τους κατάλληλους κανόνες CSS στο mouseenter και mouseleave γεγονότα, παρόμοια με αυτό:

Παρόλο που ο κώδικας κάνει το τέχνασμα, το ένστικτό μου πάντα μου έλεγε ότι πρέπει να υπάρχει κάποιος καθαρός τρόπος CSS για να επιτευχθεί το ίδιο αποτέλεσμα. Πριν από μερικά χρόνια, ενώ δούλευα σε ένα συγκεκριμένο ρυθμιστικό για την εταιρεία μου, κατέληξα σε μια παρόμοια λύση πώς ο Chris Geelhoed αναδημιουργούσε το διάσημο animation της αρχικής σελίδας του Netflix και κατάλαβα ότι δεν χρειαζόμουν πλέον JavaScript για αυτό.

Πριν από μερικούς μήνες προσπαθούσα να εφαρμόσω την ίδια προσέγγιση σε μια τροφοδοσία βάσει δικτύου στον ιστότοπο της εταιρείας μου και — boom — δεν λειτούργησε λόγω του κενού μεταξύ των στοιχείων!

Ευτυχώς για μένα, φάνηκε ότι δεν χρειάζεται να παραμείνει έτσι και για άλλη μια φορά δεν χρειαζόμουν 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;
    }

    Αυτό το παράδειγμα κώδικα θα δημιουργήσει τρία στοιχεία λίστας που καταλαμβάνουν τρεις στήλες σε ένα πλέγμα.

    Η δύναμη των επιλογέων CSS

    Τώρα, ας προσθέσουμε λίγη διαδραστικότητα. Η προσέγγιση που εφάρμοσα αρχικά βασίστηκε σε δύο βήματα:

    1. αν αιωρείται πάνω στο δοχείο θα πρέπει να αλλάξει το στυλ όλων των στοιχείων μέσα…  
    2. …εκτός από αυτόν που αιωρείται ο κέρσορας αυτή τη στιγμή.

    Ας ξεκινήσουμε με το να αρπάζουμε κάθε παιδί ενώ ο κέρσορας αιωρείται πάνω από το δοχείο:

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

    Δεύτερον, ας εξαιρέσουμε το στοιχείο που βρίσκεται επί του παρόντος και ας μειώσουμε το opacity οποιουδήποτε άλλου παιδιού:

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

    Και αυτό θα ήταν απολύτως αρκετό για δοχεία χωρίς κενά μεταξύ των θυγατρικών στοιχείων:

    Κινούμενο GIF ενός δρομέα ποντικιού που αλληλεπιδρά με στοιχεία που δεν χωρίζονται από κανένα κενά.
    Επίδειξη μιας λύσης που λειτουργεί χωρίς κενά.

    Ωστόσο, στην περίπτωσή μου, δεν μπόρεσα να αφαιρέσω αυτά τα κενά:

    Κινούμενο GIF ενός δρομέα του ποντικιού που αιωρείται πάνω από στοιχεία. Ωστόσο, όταν το ποντίκι εισέρχεται σε ένα κενό μεταξύ δύο στοιχείων, το εφέ τελειώνει καθώς το ποντίκι φεύγει από το στοιχείο.
    Επίδειξη του προβλήματος που παρουσιάζεται όταν εισάγονται κενά.

    Όταν μετακινούσα το ποντίκι ανάμεσα στα πλακάκια, όλα τα παιδικά στοιχεία ξεθώριαζαν.

    Αγνοώντας τα κενά

    Μπορούμε να υποθέσουμε ότι τα κενά είναι μέρη του δοχείου που δεν επικαλύπτονται από τα παιδιά του. Δεν θέλουμε να εκτελούμε το εφέ κάθε φορά που ο δρομέας εισέρχεται στο κοντέινερ, αλλά όταν αιωρείται πάνω από ένα από τα στοιχεία μέσα. Μπορούμε τότε να αγνοήσουμε τον κέρσορα που κινείται πάνω από τα κενά; 

    Ναι, μπορούμε, χρησιμοποιώντας pointer-events: none σχετικά με την .grid δοχείο και φέρνοντάς τα πίσω με pointer-events: auto στα παιδιά της:

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

    Ας προσθέσουμε απλώς μια ωραία μετάβαση στην αδιαφάνεια και έχουμε ένα έτοιμο στοιχείο:

    Είναι πιθανώς ακόμα πιο δροσερό όταν προσθέτουμε περισσότερα πλακίδια και δημιουργούμε μια δισδιάστατη διάταξη:

    Το τελικό 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 Το στυλ θα αγνοούσε όχι μόνο το γεγονός hover αλλά και όλα τα άλλα. Σε τέτοιες περιπτώσεις, μπορείτε να τυλίξετε το .grid σε άλλο δοχείο, όπως αυτό:

    Χαρακτηριστικά

    Σας ενθαρρύνω να πειραματιστείτε και να προσπαθήσετε να βρείτε μια απλούστερη και πιο εγγενή προσέγγιση για εργασίες που συνήθως αναμένεται να έχουν κάποιο επίπεδο πολυπλοκότητας. Οι τεχνολογίες Ιστού, όπως το CSS, γίνονται ολοένα και πιο ισχυρές και χρησιμοποιώντας εξωγενείς εγγενείς λύσεις μπορείτε να επιτύχετε εξαιρετικά αποτελέσματα χωρίς να χρειάζεται να διατηρήσετε τον κώδικά σας και να τον εκχωρήσετε σε προμηθευτές προγραμμάτων περιήγησης.

    Ελπίζω να σας άρεσε αυτό το σύντομο σεμινάριο και να το βρήκατε χρήσιμο. Ευχαριστώ!

    Ο συγγραφέας επέλεξε το Tech Εκπαίδευση να λάβει μια δωρεά ως μέρος του Γράψτε για Δωρεές προγράμματος.

    Σφραγίδα ώρας:

    Περισσότερα από Κόλπα CSS