Schäfer sind gut darin, ihre Schafe zu hüten und Ordnung und Struktur in ihre Herden zu bringen. Selbst wenn es Hunderte dieser wolligen Tiere gibt, treibt ein Schäfer sie am Ende des Tages zurück zum Hof.
Wenn Programmierer mit Daten arbeiten, wissen sie oft nicht, ob diese korrekt gefiltert oder sortiert sind. Dies ist besonders schmerzhaft, wenn man durch ein Array iteriert und die Daten dann auf einer Website anzeigt, ohne die Positionen jedes Elements zu kennen, das sie empfängt. Der Grid Shepherd ist eine Technik, die hilft, Elemente dort zu positionieren und zu sortieren, wo man sie haben möchte, und zwar mithilfe von CSS Grid anstelle von JavaScript.
Darum geht es in diesem Beitrag. Die Grid Shepherd-Technik kann Ordnung und Struktur in die Daten bringen, mit denen wir arbeiten, und uns gleichzeitig mehr Einblick geben, wo und wie sie verwendet werden, als wir es sonst könnten.
Lassen Sie uns eintauchen.
Sortieren mit JavaScript
Wir beginnen mit der Iteration über ein unsortiertes Array von Bauernhoftieren. Stellen Sie sich vor, Kühe und Schafe grasen glücklich auf den Feldern. Sie können programmgesteuert mit der Methode Array.prototype.sort gruppiert und auf einer Seite aufgelistet werden.
let animals = [
{ name: 'Edna', animal: 'cow' },
{ name: 'Liam', animal: 'sheep' },
{ name: 'Fink', animal: 'sheep' },
{ name: 'Olga', animal: 'cow' },
]
let sortedAnimals = animals.sort((a, b) => {
if (a.animal < b.animal) return -1
if (a.animal > b.animal) return 1
return 0
})
console.log(sortedAnimals)
/* Returns:
[ { name: 'Elga', animal: 'cow' },
{ name: 'Olga', animal: 'cow' },
{ name: 'Liam', animal: 'sheep' },
{ name: 'Fink', animal: 'sheep' } ]
*/
Lernen Sie den Grid Shepherd kennen
Die Grid Shepherd-Methode ermöglicht das Sortieren von Daten ohne JavaScript. Stattdessen verlassen wir uns darauf, dass CSS Grid die Arbeit für uns erledigt.
Die Struktur ist genau dieselbe wie beim JavaScript-Array von Objekten oben, nur eben als DOM-Knoten dargestellt.
<main>
<div class="cow">Edna</div>
<div class="sheep">Liam</div>
<div class="sheep">Jenn</div>
<div class="cow">Fink</div>
</main>
Sehen Sie den Pen
1. Start von David Bernegger (@Achilles_2)
auf CodePen.
Um die Tiere zu hüten, müssen wir sie in einem gemeinsamen Bereich einzäunen, wofür wir das <main>-Element verwenden. Indem wir diesen Zaun mit display: grid setzen, erstellen wir einen Grid-Formatierungskontext, in dem wir die Spalte (oder Zeile) definieren können, die jedes Tier einnehmen soll.
.sheep { grid-column: 1; }
.cow { grid-column: 2; }
Und mit grid-auto-flow: dense ordnet sich jedes Tier selbst in den ersten verfügbaren Platz jedes definierten Bereichs ein. Dies kann auch mit beliebig vielen verschiedenen Sortieroptionen verwendet werden – definieren Sie einfach eine weitere Spalte und die Daten werden magisch dorthin geleitet.
main
display: grid;
grid-auto-flow: dense;
}
.sheep { grid-column: 1; }
.cow { grid-column: 2; }
Sehen Sie den Pen
2. Finale von David Bernegger (@Achilles_2)
auf CodePen.
Profi-Hüten
Wir können unser Hütebeispiel mit CSS-Zählern weiter ausbauen. So können wir zählen, wie viele Tiere wir in jeder Spalte haben, und – indem wir Heydon Pickerings Mengenabfragen aus Leas Vortrag von 2011 anwenden – sie bedingt stylen, je nachdem, wie viele es sind.
Mengenabfragen beruhen auf einer Art Selektor zum Zählen der Klassen – was mit der Pseudo-Klassen-Notation :nth-child(An+B [of S]?) großartig wäre, aber diese ist derzeit nur in Safari verfügbar). Das bedeutet, wir müssen den Selektor :nth-of-type() als Workaround verwenden.
Dafür benötigen wir neue Elementtypen. Dies könnte durch Web Components realisiert werden oder durch Umbenennen eines beliebigen HTML-Elements in einen benutzerdefinierten Namen. Dies funktioniert auch dann, wenn diese Elemente nicht im HTML-Standard enthalten sind, da Browser HTMLUnknownElement für undefinierte Tags verwenden, was dazu führt, dass sie sich wie ein Div verhalten. Das Dokument sieht nun so aus.
<fence>
<sheep>Lisa</sheep>
<sheep>Bonnie</sheep>
<cow>Olaf</cow>
<sheep>Jenn</sheep>
</fence>
Jetzt können wir auf unsere benutzerdefinierten Elementtypen zugreifen. Wir wenden einen roten Hintergrund an, wenn die Anzahl der Schafe oder Kühe gleich oder kleiner als 10 ist.
sheep:nth-last-of-type(n+10),
sheep:nth-last-of-type(n+10) ~ sheep,
cow:nth-last-of-type(n+10),
cow:nth-last-of-type(n+10) ~ cow, {
background-color: red;
}
Zusätzlich können die Zähler einfach durch die Verwendung von counter-reset: countsheep countcow; auf dem Elternelement realisiert werden, und mit dem `before`-Selektor können die einzelnen Elemente angesprochen und gezählt werden.
sheep::before {
counter-increment: countsheep;
content: counter(countsheep);
}
Hier greifen wir auf Vue zurück, um Tiere dynamisch hinzuzufügen und zu entfernen, indem wir Vue-Übergänge mit zwei verschiedenen Sortieroptionen verwenden. Beobachten Sie, wie die Tiere natürlich die richtigen Spalten einnehmen, selbst wenn weitere hinzugefügt und einige entfernt werden.
Sehen Sie den Pen
3. Finale mit Vue-Übergängen von David Bernegger (@Achilles_2)
auf CodePen.
Grid Shepherd kann auch mit beliebigen unsortierten Daten verwendet werden, um
- Wähler in einer Umfrage zu trennen und zu zählen (vielleicht als zwei Abschnitte mit ihrem entsprechenden Profilbild) mit Live-Einfügung;
- Personen/Kollegen nach ihrer Position, ihrem Alter, ihrer Größe zu gruppieren; und
- beliebige hierarchische Strukturen zu erstellen.
Hüten und Zugänglichkeit
grid-auto-flow: dense ändert die DOM-Struktur des Grids nicht – es ordnet die enthaltenen Elemente lediglich visuell neu an. Ein Nebeneffekt ist im letzten Beispiel beim alphabetischen Sortieren zu sehen, da die counter-Nummern durcheinander geraten. Das Ändern der DOM-Struktur wirkt sich nicht nur auf Personen aus, die Screenreader verwenden, sondern auch auf die Tab-Navigation.
Beachten Sie auch, dass eine flache Dokumentstruktur für Screenreader möglicherweise nicht gut ist. Stattdessen würde ich diese präsentationsbezogenen Grids als Graphen behandeln und die Informationen mit einer längeren textlichen Alternative bereitstellen.
Sammeln wir sie ein!
Es ist ziemlich faszinierend zu sehen, wie ein leistungsstarkes CSS-Layout-Tool wie Grid für Anwendungsfälle genutzt werden kann, die über traditionelle Layout-Anforderungen hinausgehen und in Bereiche fallen, für die wir früher andere Sprachen verwendet hätten. In diesem Fall sehen wir, wie sich die Layout-Vorteile von CSS Grid und die dynamischen Datenverarbeitungsfähigkeiten von JavaScript überschneiden und wie uns das mehr Wahlmöglichkeiten – und mehr Macht – gibt, gerenderte Daten nach unserem Willen zu formen.
Das ist ziemlich cool, obwohl ich mich frage, wie viele Anwendungsfälle es geben würde. Dem Beispiel des Artikels folgend, wenn Sie zwei verschiedene Listen anzeigen müssen, sollten diese wirklich in separaten
<ul>-Tags stehen.Spitze.
Ich frage mich, wie zugänglich das wäre. Eine Option, die schön wäre, wenn die UI das visuelle Erscheinungsbild übernimmt, wäre vielleicht, nach Typ zu sortieren und zu rendern, sodass alles Gleiche zusammen ist?