Νοημοσύνη δεδομένων Πλάτωνα.
Κάθετη Αναζήτηση & Αι.

Εξερεύνηση του σιωπηρού πλέγματος και των δυνατοτήτων αυτόματης τοποθέτησης του CSS Grid

Ημερομηνία:

Όταν εργάζεστε με το CSS Grid, το πρώτο πράγμα που πρέπει να κάνετε είναι να ορίσετε display: grid στο στοιχείο που θέλουμε να γίνει ένα δοχείο πλέγματος. Στη συνέχεια ορίζουμε ρητά το πλέγμα χρησιμοποιώντας έναν συνδυασμό των grid-template-columns, grid-template-rows, να grid-template-areas. Και από εκεί, το επόμενο βήμα είναι να τοποθετήσετε αντικείμενα μέσα στο πλέγμα.

Αυτή είναι η κλασική προσέγγιση που πρέπει να χρησιμοποιείται και την προτείνω επίσης. Ωστόσο, υπάρχει μια άλλη προσέγγιση για τη δημιουργία πλεγμάτων χωρίς ρητό ορισμό. Αυτό το ονομάζουμε το άρρητο πλέγμα.

Πίνακας περιεχομένων

«Ρητή, άρρητη; Τι στο καλό συμβαίνει εδώ;»

Περίεργοι όροι, σωστά; Ο Μανουέλ Ματούζοβιτς ήδη έχει μια καλή εξήγηση του τι μπορούμε να λέμε "σιωπηρό" και "ρητό" στο CSS Grid, αλλά ας σκάψουμε κατευθείαν σε αυτό ο specification λέει:

Η grid-template-rows, grid-template-columns, να grid-template-areas Οι ιδιότητες ορίζουν έναν σταθερό αριθμό κομματιών που σχηματίζονται το ρητό πλέγμα. Όταν τα στοιχεία πλέγματος τοποθετούνται εκτός αυτών των ορίων, το κοντέινερ πλέγματος δημιουργεί σιωπηρά κομμάτια πλέγματος προσθέτοντας άδηλες γραμμές πλέγματος στο πλέγμα. Αυτές οι γραμμές μαζί με το ρητό πλέγμα σχηματίζουν το άρρητο πλέγμα.

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

Τι γίνεται με την αυτόματη τοποθέτηση;

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

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

Δυναμική πλαϊνή γραμμή

Εδώ, έχουμε τρεις διαφορετικές διατάξεις, αλλά έχουμε μόνο μία διαμόρφωση πλέγματος που λειτουργεί για όλες.

main {
  display: grid;
  grid-template-columns: 1fr;
}

Μόνο μία στήλη καταλαμβάνει όλο τον ελεύθερο χώρο. Αυτό είναι το «ρητό» πλέγμα μας. Έχει ρυθμιστεί ώστε να χωράει ένα στοιχείο πλέγματος στο main δοχείο πλέγματος. Αυτό είναι όλο. Μία στήλη και μία σειρά:

Αλλά τι θα γινόταν αν αποφασίσαμε να ρίξουμε ένα άλλο στοιχείο εκεί, ας πούμε ένα aside (η δυναμική πλαϊνή μπάρα μας). Όπως ορίζεται αυτήν τη στιγμή (και ρητά), το πλέγμα μας θα πρέπει να προσαρμοστεί αυτόματα για να βρει μια θέση για αυτό το στοιχείο. Και αν δεν κάνουμε τίποτα άλλο με το CSS μας, ορίστε τι μας λέει ότι συμβαίνει το DevTools.

Το στοιχείο καταλαμβάνει ολόκληρη τη στήλη που έχει οριστεί ρητά στο κοντέινερ. Εν τω μεταξύ, το πέφτει σε μια νέα σειρά μεταξύ σιωπηρών γραμμών πλέγματος με τις ετικέτες 2 και 3. Σημειώστε ότι χρησιμοποιώ ένα 20px κενό για να βοηθήσει να διαχωριστούν τα πράγματα οπτικά.

Μπορούμε να μετακινήσουμε το <aside> σε μια στήλη δίπλα στο <section>:

aside {
  grid-column-start: 2;
}

Και να τι μας λέει τώρα το DevTools:

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

Τοποθετούμε το στοιχείο μας στη δεύτερη στήλη αλλά... δεν έχουμε δεύτερη στήλη. Παράξενο, σωστά; Δεν δηλώσαμε ποτέ δεύτερη στήλη στο <main> κοντέινερ πλέγματος, αλλά το πρόγραμμα περιήγησης δημιούργησε ένα για εμάς! Αυτό είναι το βασικό μέρος από τις προδιαγραφές που εξετάσαμε:

Όταν τα στοιχεία πλέγματος τοποθετούνται εκτός αυτών των ορίων, το κοντέινερ πλέγματος δημιουργεί σιωπηρά κομμάτια πλέγματος προσθέτοντας άδηλες γραμμές πλέγματος στο πλέγμα.

Αυτό το ισχυρό χαρακτηριστικό μας επιτρέπει να έχουμε δυναμικές διατάξεις. Αν έχουμε μόνο το <section> στοιχείο, το μόνο που παίρνουμε είναι μια στήλη. Αν όμως προσθέσουμε ένα <aside> στοιχείο στο μείγμα, δημιουργείται μια επιπλέον στήλη για να το περιέχει.

Θα μπορούσαμε να τοποθετήσουμε το <aside> πριν από <section> αντί για αυτό:

aside {
  grid-column-end: -2;
} 

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

Μπορούμε να έχουμε είτε δεξιά είτε αριστερή πλαϊνή μπάρα

Μπορούμε να κάνουμε το ίδιο πράγμα πιο εύκολα χρησιμοποιώντας το grid-auto-flow ιδιότητα για να ορίσετε οποιαδήποτε και όλα τα έμμεσα ίχνη να ρέουν σε α column κατεύθυνση:

Τώρα δεν χρειάζεται να διευκρινίσουμε grid-column-start για να τοποθετήσετε το <aside> στοιχείο στα δεξιά του <section>! Στην πραγματικότητα, οποιοδήποτε άλλο στοιχείο πλέγματος αποφασίσουμε να ρίξουμε εκεί ανά πάσα στιγμή θα ρέει τώρα προς μια κατεύθυνση στήλης, το καθένα τοποθετημένο στις δικές του σιωπηρές διαδρομές πλέγματος. Ιδανικό για καταστάσεις όπου ο αριθμός των στοιχείων στο πλέγμα δεν είναι γνωστός εκ των προτέρων!

Τούτου λεχθέντος, χρειαζόμαστε ακόμα grid-column-end αν θέλουμε να το τοποθετήσουμε σε μια στήλη στα αριστερά του γιατί, διαφορετικά, το <aside> θα καταλάβει τη ρητή στήλη η οποία, με τη σειρά της, ωθεί το <section> έξω από το ρητό πλέγμα και το αναγκάζει να πάρει τη σιωπηρή στήλη.

Ξέρω ξέρω. Αυτό είναι λίγο μπερδεμένο. Ακολουθεί ένα άλλο παράδειγμα που μπορούμε να χρησιμοποιήσουμε για να κατανοήσουμε καλύτερα αυτή τη μικρή ιδιορρυθμία:

Στο πρώτο παράδειγμα, δεν προσδιορίσαμε καμία τοποθέτηση. Σε αυτήν την περίπτωση, το πρόγραμμα περιήγησης θα τοποθετήσει πρώτα το <aside> στοιχείο στη ρητή στήλη αφού έρχεται πρώτο στο DOM. ο <section>, εν τω μεταξύ, τοποθετείται αυτόματα στη στήλη πλέγματος που δημιουργεί αυτόματα (ή σιωπηρά) το πρόγραμμα περιήγησης για εμάς.

Στο δεύτερο παράδειγμα, ορίσαμε το <aside> στοιχείο εκτός του ρητού πλέγματος:

aside {
  grid-column-end: -2;
}

Τώρα δεν πειράζει αυτό <aside> έρχεται πρώτη στην HTML. Με εκ νέου ανάθεση <aside> κάπου αλλού, το έχουμε φτιάξει <section> στοιχείο διαθέσιμο για λήψη της ρητής στήλης.

Πλέγμα εικόνας

Ας δοκιμάσουμε κάτι διαφορετικό με ένα πλέγμα εικόνων όπου έχουμε μια μεγάλη εικόνα και μερικές μικρογραφίες δίπλα της (ή κάτω από αυτήν).

Έχουμε δύο διαμορφώσεις πλέγματος. Αλλά μάντεψε τι? Δεν ορίζω κανένα πλέγμα καθόλου! Το μόνο που κάνω είναι αυτό:

.grid img:first-child {
  grid-area: span 3 / span 3;
}

Είναι εκπληκτικό ότι χρειαζόμαστε μόνο μία γραμμή κώδικα για να βγάλουμε κάτι τέτοιο, οπότε ας αναλύσουμε τι συμβαίνει και θα δείτε ότι είναι πιο εύκολο από ό,τι νομίζετε. Πρωτα απο ολα, grid-area είναι μια συντομογραφία που συνδυάζει τις ακόλουθες ιδιότητες σε μια ενιαία δήλωση:

  • grid-row-start
  • grid-row-end
  • grid-column-start
  • grid-column-end

Περίμενε! Δεν είναι grid-area την ιδιότητα που χρησιμοποιούμε για να ορίσουμε ονομασμένες περιοχές αντί για το πού αρχίζουν και τελειώνουν τα στοιχεία στο πλέγμα;

Ναι, αλλά κάνει και περισσότερα. Θα μπορούσαμε να γράψουμε πολλά περισσότερα grid-area, αλλά στη συγκεκριμένη περίπτωση:

.grid img:first-child {
  grid-area: span 3 / span 3;
}

/* ...is equivalent to: */
.grid img:first-child {
  grid-row-start: span 3;
  grid-column-start: span 3;
  grid-row-end: auto;
  grid-column-end: auto;
}

Μπορούμε να δούμε το ίδιο πράγμα όταν ανοίγουμε το DevTools για να επεκτείνουμε τη σύντομη έκδοση:

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

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

Συνοψίζοντας, είπαμε στο πρόγραμμα περιήγησης ότι η πρώτη εικόνα πρέπει να καταλαμβάνει το χώρο τριών στηλών και τριών σειρών που ποτέ δεν ορίσαμε ρητά κατά τη ρύθμιση του κοντέινερ πλέγματος. Το πρόγραμμα περιήγησης έθεσε αυτές τις στήλες και τις σειρές για εμάς. Σαν άποτέλεσμα, οι υπόλοιπες εικόνες στο HTML ρέουν στη θέση τους χρησιμοποιώντας τις ίδιες τρεις στήλες και γραμμές. Και δεδομένου ότι η πρώτη εικόνα καταλαμβάνει και τις τρεις στήλες της πρώτης σειράς, οι υπόλοιπες εικόνες ρέουν σε πρόσθετες σειρές που η καθεμία περιέχει τρεις στήλες, όπου κάθε εικόνα καταλαμβάνει μία στήλη.

Όλα αυτά από μια γραμμή CSS! Αυτή είναι η δύναμη του «σιωπηρού» πλέγματος» και της αυτόματης τοποθέτησης.

Για τη δεύτερη διαμόρφωση πλέγματος σε αυτήν την επίδειξη, το μόνο που έχω κάνει είναι να αλλάξω την αυτόματη κατεύθυνση ροής χρησιμοποιώντας grid-auto-flow: column με τον ίδιο τρόπο που κάναμε νωρίτερα όταν τοποθετούσαμε ένα <aside> στοιχείο δίπλα στο α <section>. Αυτό αναγκάζει το πρόγραμμα περιήγησης να δημιουργήσει ένα τέταρτος στήλη που μπορεί να χρησιμοποιήσει για να τοποθετήσει τις υπόλοιπες εικόνες. Και αφού έχουμε τρεις σειρές, οι υπόλοιπες εικόνες τοποθετούνται στην ίδια κάθετη στήλη.

Πρέπει να προσθέσουμε μερικές ιδιότητες στις εικόνες για να βεβαιωθούμε ότι ταιριάζουν καλά στο πλέγμα χωρίς υπερχείλιση:

.grid {
  display: grid;
  grid-gap: 10px;
}

/* for the second grid configuration */
.horizontal {
  grid-auto-flow: column;
}

/* The large 3⨉3 image */
.grid img:first-child {
  grid-area: span 3 / span 3;
}

/* Help prevent stretched or distorted images */
img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

Και φυσικά, μπορούμε εύκολα να ενημερώσουμε το πλέγμα για να εξετάσουμε περισσότερες εικόνες προσαρμόζοντας μία τιμή. Αυτό θα ήταν το 3 στα στυλ για τη μεγάλη εικόνα. Έχουμε αυτό:

.grid img:first-child {
  grid-area: span 3 / span 3;
}

Αλλά θα μπορούσαμε να προσθέσουμε μια τέταρτη στήλη απλά αλλάζοντας την σε 4 αντι αυτου:

.grid img:first-child {
  grid-area: span 4 / span 4;
}

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

Δυναμικές διατάξεις

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

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

Όταν έχουμε ένα στοιχείο, δεν κάνουμε τίποτα. Το στοιχείο θα τεντωθεί για να γεμίσει τη μοναδική γραμμή και στήλη που δημιουργούνται αυτόματα από το πλέγμα.

Bit όταν προσθέτουμε το δεύτερο στοιχείο, δημιουργούμε μια άλλη (σιωπηρή) στήλη χρησιμοποιώντας grid-column-start: 2.

Όταν προσθέτουμε ένα τρίτο στοιχείο, θα πρέπει να καταλαμβάνει το πλάτος δύο στηλών — γι' αυτό το χρησιμοποιήσαμε grid-column-start: span 2, αλλά μόνο αν είναι το :last-child γιατί αν (και πότε) προσθέσουμε ένα τέταρτο στοιχείο, αυτό θα πρέπει να καταλαμβάνει μόνο μια στήλη.

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

.grid {
  display: grid;
}
.grid :nth-child(2) {
  grid-column-start: 2;
}
.grid :nth-child(3):last-child {
  grid-column-start: span 2;
}

Ας δοκιμάσουμε ένα άλλο:

Δεν κάνουμε τίποτα για την πρώτη και τη δεύτερη περίπτωση όπου έχουμε μόνο ένα ή δύο στοιχεία. Όταν προσθέτουμε ένα τρίτο στοιχείο, ωστόσο, λέμε στο πρόγραμμα περιήγησης ότι — αρκεί να είναι το :last-child — θα πρέπει να εκτείνεται σε δύο στήλες. Όταν προσθέτουμε ένα τέταρτο στοιχείο, λέμε στο πρόγραμμα περιήγησης ότι το στοιχείο πρέπει να τοποθετηθεί στη δεύτερη στήλη.

.grid {
  display: grid;
}
.grid :nth-child(3):last-child {
  grid-column-start: span 2;
}
.grid :nth-child(4) {
  grid-column-start: 2;
}

Αρχίζεις να καταλαβαίνεις το κόλπο; Δίνουμε στο πρόγραμμα περιήγησης συγκεκριμένες οδηγίες με βάση τον αριθμό των στοιχείων (χρησιμοποιώντας :nth-child) και, μερικές φορές, μια εντολή μπορεί να αλλάξει εντελώς τη διάταξη.

Θα πρέπει να σημειωθεί ότι το μέγεθος δεν θα είναι το ίδιο όταν εργαζόμαστε με διαφορετικό περιεχόμενο:

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

grid-auto-rows: 1fr;
grid-auto-columns: 1fr;

Γεια, δεν έχουμε παίξει με αυτές τις ιδιότητες ακόμα! grid-auto-rows και grid-auto-columns ορίστε το μέγεθος των σιωπηρών σειρών και στηλών, αντίστοιχα, σε ένα κοντέινερ πλέγματος. Ή, όπως το spec εξηγεί:

Η grid-auto-columns και grid-auto-rows Οι ιδιότητες καθορίζουν το μέγεθος των κομματιών που δεν έχουν εκχωρηθεί μέγεθος από grid-template-rows or grid-template-columns.

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

Ακόμη και με έξι στοιχεία, χρειαζόμασταν μόνο δύο δηλώσεις. Φανταστείτε όλες τις πολύπλοκες και δυναμικές διατάξεις που μπορούμε να πετύχουμε με μερικές γραμμές κώδικα!

Τι συμβαίνει με αυτό grid-auto-rows και γιατί παίρνει τρεις τιμές; Ορίζουμε τρεις σειρές;

Όχι, δεν ορίζουμε τρεις σειρές. Αλλά εμείς are ορίζοντας τρεις τιμές ως μοτίβο για τις σιωπηρές σειρές μας. Η λογική είναι η εξής:

  • Αν έχουμε μία σειρά, θα πάρει μέγεθος με την πρώτη τιμή.
  • Αν έχουμε δύο σειρές, η πρώτη παίρνει την πρώτη τιμή και η δεύτερη τη δεύτερη τιμή.
  • Εάν έχουμε τρεις σειρές, οι τρεις τιμές θα χρησιμοποιηθούν.
  • Αν έχουμε τέσσερις σειρές (και εδώ έρχεται το ενδιαφέρον μέρος), χρησιμοποιούμε τις τρεις τιμές για τις τρεις πρώτες σειρές και επαναχρησιμοποιούμε την πρώτη τιμή ξανά για την τέταρτη σειρά. Γι' αυτό είναι ένα είδος μοτίβου που επαναλαμβάνουμε για να μετρήσουμε όλες τις σιωπηρές σειρές.
  • Αν έχουμε 100 σειρές, θα έχουν το μέγεθος τρεις προς τρεις για να έχουμε 2fr 2fr 1fr 2fr 2fr 1fr 2fr 2fr 1frΚ.λπ.

Σε αντίθεση με grid-template-rows που ορίζει τον αριθμό των σειρών και τα μεγέθη τους, grid-auto-rows μόνο σειρά μεγεθών που μπορεί να δημιουργηθούν στην πορεία.

Αν επιστρέψουμε στο παράδειγμά μας, η λογική είναι να έχουμε ίσο μέγεθος όταν δημιουργούνται δύο σειρές (θα χρησιμοποιήσουμε το 2fr 2fr), αλλά αν δημιουργηθεί μια τρίτη σειρά την κάνουμε λίγο μικρότερη.

Μοτίβα πλέγματος

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

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

Ρίξτε μια ματιά στον κώδικα. Μπορεί να φαίνεται περίπλοκο, αλλά ας το αναλύσουμε γιατί καταλήγει να είναι αρκετά απλό.

Το πρώτο πράγμα που πρέπει να κάνετε είναι να προσδιορίσετε το μοτίβο. Ρωτήστε τον εαυτό σας: "Μετά από πόσα στοιχεία πρέπει να επαναληφθεί το μοτίβο;" Σε αυτή την περίπτωση είναι μετά από κάθε τέσσερα στοιχεία. Λοιπόν, ας δούμε τη χρήση μόνο τεσσάρων στοιχείων προς το παρόν:

Τώρα, ας ορίσουμε το πλέγμα και ας ρυθμίσουμε το γενικό μοτίβο χρησιμοποιώντας το :nth-child επιλογέας για εναλλαγή μεταξύ στοιχείων:

.grid {
  display: grid;
  grid-auto-columns: 1fr; /* all the columns are equal */
  grid-auto-rows: 100px; /* all the rows equal to 100px */
}
.grid :nth-child(4n + 1) { /* ?? */ }
.grid :nth-child(4n + 2) { /* ?? */ }
.grid :nth-child(4n + 3) { /* ?? */ }
.grid :nth-child(4n + 4) { /* ?? */ }

Είπαμε ότι το μοτίβο μας επαναλαμβάνεται κάθε τέσσερα στοιχεία, οπότε λογικά θα το χρησιμοποιήσουμε 4n + x όπου x κυμαίνεται από 1 έως 4. Είναι λίγο πιο εύκολο να εξηγήσετε το μοτίβο ως εξής:

4(0) + 1 = 1 = 1st element /* we start with n = 0 */
4(0) + 2 = 2 = 2nd element
4(0) + 3 = 3 = 3rd element
4(0) + 4 = 4 = 4th element
4(1) + 1 = 5 = 5th element /* our pattern repeat here at n = 1 */
4(1) + 2 = 6 = 6th element
4(1) + 3 = 7 = 7th element
4(1) + 4 = 8 = 8th element
4(2) + 1 = 9 = 9th element /* our pattern repeat again here at n = 2 */
etc.

Τέλειο, σωστά; Έχουμε τέσσερα στοιχεία και επαναλαμβάνουμε το μοτίβο στο πέμπτο στοιχείο, το ένατο στοιχείο και ούτω καθεξής.

Εκείνοι :nth-child οι επιλογείς μπορεί να είναι δύσκολοι! Ο Chris έχει μια πολύ χρήσιμη εξήγηση για το πώς λειτουργούν όλα, Συμπεριλαμβανομένων των συνταγές για τη δημιουργία διαφορετικών μοτίβων.

Τώρα διαμορφώνουμε κάθε στοιχείο έτσι ώστε:

  1. Το πρώτο στοιχείο πρέπει να έχει δύο στήλες και να ξεκινά από τη στήλη ένα (grid-column: 1/span 2).
  2. Το δεύτερο στοιχείο τοποθετείται στην τρίτη στήλη (grid-column-start: 3).
  3. Το τρίτο στοιχείο τοποθετείται στην πρώτη στήλη: (grid-column-start: 1).
  4. Το τέταρτο στοιχείο παίρνει δύο στήλες και ξεκινά από τη δεύτερη στήλη: (grid-column: 2/span 2).

Εδώ είναι σε CSS:

.grid {
  display: grid;
  grid-auto-columns: 1fr; /* all the columns are equal */
  grid-auto-rows: 100px; /* all the rows are equal to 100px */
}
.grid :nth-child(4n + 1) { grid-column: 1/span 2; }
.grid :nth-child(4n + 2) { grid-column-start: 3; }
.grid :nth-child(4n + 3) { grid-column-start: 1; }
.grid :nth-child(4n + 4) { grid-column: 2/span 2; }

Θα μπορούσαμε να σταματήσουμε εδώ και να τελειώσουμε… αλλά μπορούμε καλύτερα! Συγκεκριμένα, μπορούμε να αφαιρέσουμε ορισμένες δηλώσεις και να βασιστούμε στις εξουσίες αυτόματης τοποθέτησης του δικτύου για να κάνουμε τη δουλειά για εμάς. Αυτό είναι το πιο δύσκολο κομμάτι για το grok και απαιτεί πολλή εξάσκηση για να μπορέσετε να προσδιορίσετε τι μπορεί να αφαιρεθεί.

Το πρώτο πράγμα που μπορούμε να κάνουμε είναι να ενημερώσουμε grid-column: 1 /span 2 και χρήση μόνο grid-column: span 2 αφού, από προεπιλογή, το πρόγραμμα περιήγησης θα τοποθετήσει το πρώτο στοιχείο στην πρώτη στήλη. Μπορούμε επίσης να αφαιρέσουμε αυτό:

.grid :nth-child(4n + 3) { grid-column-start: 1; }

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

.grid {
  display: grid;
  grid-auto-rows: 100px; /* all the rows are equal to 100px */
  grid-auto-columns: 1fr; /* all the columns are equal */
}
.grid :nth-child(4n + 1) { grid-column: span 2; }
.grid :nth-child(4n + 2) { grid-column-start: 2; }
.grid :nth-child(4n + 4) { grid-column: 2/span 2; }

Αλλά έλα, μπορούμε να περπατήσουμε καλύτερα! Μπορούμε επίσης να αφαιρέσουμε αυτό:

.grid :nth-child(4n + 2) { grid-column-start: 2; }

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

Νομίζω ότι ξέρεις το τέλος της ιστορίας. Το πρόγραμμα περιήγησης θα τοποθετήσει αυτόματα το δεύτερο και το τρίτο στοιχείο σε αυτά τα κενά σημεία. Έτσι ο κώδικας μας γίνεται ακόμα πιο απλός:

.grid {
  display: grid;
  grid-auto-columns: 1fr; /* all the columns are equal */
  grid-auto-rows: 100px; /* all the rows are equal to 100px */
}
.grid :nth-child(4n + 1) { grid-column: span 2; }
.grid :nth-child(4n + 4) { grid-column: 2/span 2; }

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

Γιατί να μην χρησιμοποιήσετε grid-template-columns να ορίσουμε ρητές στήλες αφού γνωρίζουμε τον αριθμό των στηλών;

Μπορούμε να το κάνουμε αυτό! Εδώ είναι ο κωδικός για αυτό:

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* all the columns are equal */
  grid-auto-rows: 100px; /* all the rows are equal to 100px */
}
.grid :nth-child(4n + 1),
.grid :nth-child(4n + 4) {
  grid-column: span 2;
}

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

Η ρητή προσέγγιση είναι πιο απλή, ενώ ένα σιωπηρό πλέγμα απαιτεί από εσάς να - συγχωρείτε το λογοπαίγνιο - να συμπληρώσετε τα κενά όπου η CSS κάνει πρόσθετη δουλειά στα παρασκήνια. Στο τέλος, πιστεύω ότι η πλήρης κατανόηση των σιωπηρών δικτύων θα σας βοηθήσει να κατανοήσετε καλύτερα τον αλγόριθμο CSS Grid. Τελικά, δεν είμαστε εδώ για να μελετήσουμε αυτό που είναι προφανές - είμαστε εδώ για να εξερευνήσουμε άγριες περιοχές!

Ας δοκιμάσουμε ένα άλλο μοτίβο, λίγο πιο γρήγορα αυτή τη φορά:

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

.grid {
  display: grid;
  grid-auto-columns: 1fr;
  grid-auto-rows: 100px;
}
.grid :nth-child(6n + 3) {
  grid-area: span 2/2; /* grid-row-start: span 2 && grid-column-start: 2 */
}
.grid :nth-child(6n + 4) {
  grid-area: span 2/1; /* grid-row-start: span 2 && grid-column-start: 1 */
}

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

.grid :nth-child(6n + 2) {
  grid-column: 1; /* grid-column-start: 1 */
}

Καλύτερα, αλλά υπάρχει ακόμα περισσότερη δουλειά, Πρέπει να μεταφέρουμε το τρίτο στοιχείο στην κορυφή. Είναι δελεαστικό να δοκιμάσετε να το τοποθετήσετε στην πρώτη σειρά με αυτόν τον τρόπο:

.grid :nth-child(6n + 3) {
  grid-area: 1/2/span 2; 
    /* Equivalent to:
       grid-row-start: 1;
       grid-row-end: span 2;
       grid-column-start: 2 
     */
}

Αλλά αυτό δεν λειτουργεί γιατί αναγκάζει όλα τα 6n + 3 στοιχεία για να τοποθετηθούν στην ίδια περιοχή που κάνει μια μπερδεμένη διάταξη. Η πραγματική λύση είναι να διατηρήσουμε τον αρχικό ορισμό του τρίτου στοιχείου και να προσθέσουμε grid-auto-flow: dense να καλύψει τα κενά. Από το MDN:

[Ο] «πυκνός» αλγόριθμος συσκευασίας επιχειρεί να γεμίσει σε τρύπες νωρίτερα στο πλέγμα, εάν εμφανιστούν αργότερα μικρότερα αντικείμενα. Αυτό μπορεί να κάνει τα στοιχεία να εμφανίζονται εκτός σειράς, όταν κάτι τέτοιο θα γεμίσει τις τρύπες που αφήνουν μεγαλύτερα αντικείμενα. Εάν παραλειφθεί, χρησιμοποιείται ένας «αραιός» αλγόριθμος, όπου ο αλγόριθμος τοποθέτησης κινείται μόνο «εμπρός» στο πλέγμα κατά την τοποθέτηση αντικειμένων, χωρίς ποτέ να κάνει πίσω για να γεμίσει τρύπες. Αυτό διασφαλίζει ότι όλα τα αντικείμενα που τοποθετούνται αυτόματα εμφανίζονται «με τη σειρά», ακόμα κι αν αυτό αφήνει τρύπες που θα μπορούσαν να έχουν γεμίσει από μεταγενέστερα αντικείμενα.

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

Γιατί να μην προσθέτετε πάντα αυτήν την ιδιότητα από προεπιλογή;

Δεν το προτείνω γιατί, σε ορισμένες περιπτώσεις, δεν θέλουμε αυτή τη συμπεριφορά. Σημειώστε πώς η εξήγηση του MDN εκεί αναφέρει ότι κάνει τα στοιχεία να ρέουν "εκτός σειράς" για να γεμίσουν τις τρύπες που αφήνουν μεγαλύτερα αντικείμενα. Η οπτική σειρά είναι συνήθως εξίσου σημαντική με τη σειρά πηγής, ιδιαίτερα όταν πρόκειται για προσβάσιμες διεπαφές και grid-auto-flow: dense μπορεί μερικές φορές να προκαλέσει αναντιστοιχία μεταξύ της σειράς οπτικής και πηγής.

Ο τελικός μας κωδικός είναι τότε:

.grid {
  display: grid;
  grid-auto-columns: 1fr;
  grid-auto-flow: dense;
  grid-auto-rows: 100px;
}
.grid :nth-child(6n + 2) { grid-column: 1; }
.grid :nth-child(6n + 3) { grid-area: span 2/2; }
.grid :nth-child(6n + 4) { grid-row: span 2; }

Αλλο ένα? Πάμε!

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

Τα αντικείμενα με μαύρο χρώμα τοποθετούνται έμμεσα στο πλέγμα. Πρέπει να σημειωθεί ότι μπορούμε να λάβουμε την ίδια διάταξη με περισσότερους τρόπους από ό,τι έφτασα εκεί. Μπορείς να τα καταλάβεις και αυτά; Τι γίνεται με τη χρήση grid-template-columns? Μοιραστείτε τα έργα σας στην ενότητα σχολίων.

Θα σας αφήσω με ένα τελευταίο μοτίβο:

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

Θέλουν περισσότερα?

Πριν τελειώσουμε, θέλω να μοιραστώ μερικές ερωτήσεις Stack Overflow που σχετίζονται με το CSS Grid όπου μπήκα με απαντήσεις που χρησιμοποιούν πολλές από τις τεχνικές που καλύψαμε εδώ μαζί. Είναι μια καλή λίστα που δείχνει πόσες πραγματικές περιπτώσεις χρήσης και πραγματικές καταστάσεις εμφανίζονται όπου αυτά τα πράγματα είναι χρήσιμα:

Ολοκληρώνοντας

Το CSS Grid υπάρχει εδώ και χρόνια, αλλά εξακολουθούν να υπάρχουν πολλά ελάχιστα γνωστά και χρησιμοποιημένα κόλπα που δεν συζητούνται ευρέως. Το σιωπηρό πλέγμα και τα χαρακτηριστικά αυτόματης τοποθέτησης είναι δύο από αυτά!

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

Ομοίως, μπορεί να θέλετε να διαβάσετε σχετικά grid-auto-columns στο CSS-Tricks Almanac επειδή ο Mojtaba Seyedi πηγαίνει σε πολλές λεπτομέρειες και περιλαμβάνει απίστευτα χρήσιμα γραφικά για να εξηγήσει τη συμπεριφορά.

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

spot_img

Τελευταία Νοημοσύνη

spot_img

Συνομιλία με μας

Γεια σου! Πώς μπορώ να σε βοηθήσω?