Entwicklung erweiterbarer HTML- und CSS-Komponenten

Avatar of Jon Yablonski
Von Jon Yablonski am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Der folgende Beitrag ist ein Gastbeitrag von Jon Yablonski. Jon wird uns ein Beispiel zeigen, wie wir die Struktur so gestalten können, dass eine Komponente besonders vielseitig ist. Sie funktioniert wie sie ist und hat eine standardisierte Methode zur Erstellung von Variationen (durch Hinzufügen einer einzigen Klasse), die es ermöglicht, das Design an die jeweilige Situation anzupassen.

Medienmuster

Die Zeiten, in denen Webseiten mit fester Breite aus pixelgenauen Photoshop-Dateien erstellt wurden, sind vorbei. Um flexible Layouts zu erstellen, die sich intelligent an jede Bildschirmgröße anpassen, haben sich unsere Arbeitsabläufe iterativer und agiler gestaltet. Wir haben die Bedeutung von Modularität erkannt und wie sie die Flexibilität ermöglicht, die wir benötigen, um im Browser agil zu bleiben. Als Designer und Frontend-Entwickler ist diese Flexibilität für meine Herangehensweise an Webprojekte unerlässlich. Ich treffe Designentscheidungen immer häufiger im Browser als in Design-Dateien, und um diesen Workflow zu unterstützen, benötige ich die Fähigkeit, Benutzeroberflächenmodule zu erstellen, die einfach erweitert werden können.

Erweiterbare Module

Was ich sehr schätze, ist Erweiterbarkeit, ein Prinzip des Systemdesigns, bei dem die Implementierung zukünftiges Wachstum berücksichtigt. Das zentrale Thema der Erweiterbarkeit ist, Veränderungen zu ermöglichen und gleichzeitig die Auswirkungen auf das bestehende System zu minimieren. Für die Frontend-Entwicklung bedeutet dies, Modulvariationen zu erstellen, die leicht erweitert werden können, um den Anforderungen der Benutzeroberfläche gerecht zu werden, während die zugrunde liegende Basis des Moduls erhalten bleibt. Das Endergebnis ist weniger Code-Ballast, weniger Fragmentierung der Codebasis durch Einzellösungen und leichter zu wartender Code.

Für Erweiterbarkeit entwickeln

Um die Konsistenz der Struktur unserer Komponenten und Muster zu gewährleisten, müssen wir sie auf eine Weise entwickeln, die wiederholbar und vorhersehbar ist. Im Folgenden sind die grundlegenden Schritte aufgeführt, die ich unternehme

Schritt 1: Modultyp identifizieren

Der erste Schritt besteht darin, den Typ des Moduls zu identifizieren, mit dem wir arbeiten, was in eine von zwei Kategorien eingeteilt werden kann: Komponente oder Muster. Eine Komponente ist ein unabhängiges, modulares Objekt, das keine untergeordneten Elemente hat, aber Modifikatorzustände aufweisen kann, die ihr Aussehen ändern (Beispiel: Buttons, Nachrichten, Thumbnails). Ein Muster hingegen ist ein Objekt, das untergeordnete Elemente hat (die auch eigenständige Komponenten sein können), die alle vom übergeordneten Objekt beeinflusst werden (Beispiel: Header, Header-Logo, Header-Nav). Sowohl Komponenten als auch Muster können Modifikatorzustände aufweisen, die ihr Aussehen oder ihre Struktur ändern.

Schritt 2: Fundament des Moduls definieren

Der nächste Schritt ist die Definition der grundlegenden Regeln der Komponente oder des Musters, die alle Variationen der Komponente erben werden. Diese Regeln sollten relativ minimal gehalten und für Eigenschaften reserviert werden, die sich selten ändern. Meistens sind dies Eigenschaften wie Abstand, Polsterung, Position und Anzeige.

Alle Codebeispiele in diesem Artikel verwenden die BEM-Namenskonvention (Block, Element, Modifier). BEM bietet eine Reihe von Vorteilen, aber vielleicht ist mein Favorit, dass ich allein anhand des Namens erkennen kann, was ein Stück Markup tut. Wenn Sie mehr über diese Namenskonvention erfahren möchten, empfehle ich Ihnen, diesen Artikel für eine gute Einführung.

HTML-Fundament
<div class="block"></div>
CSS-Fundament
.block {
  position: relative;
  margin: 0 0 1em;
}

Schritt 3: Gemeinsame Elemente definieren

Wenn Sie eine Komponente erstellen, überspringen Sie diesen Schritt und gehen Sie direkt zum nächsten über; wenn Sie jedoch ein Muster erstellen, das untergeordnete Elemente enthält, besteht der nächste Schritt darin, gemeinsame Elemente zu definieren. Diese Elemente stehen thematisch in Beziehung zum übergeordneten Block (können aber auch außerhalb des Musters als eigenständige Komponenten existieren).

Gemeinsame HTML-Elemente
<div class="block">
  <div class="block__element">…</div>
  <div class="block__another-element">…</div>
</div>
CSS
.block__element {
  padding: 1em;
  background: white;
  border: 1px solid black;
}

.block__another-element {
  position: absolute;
  top: 0;
  right: 0;
}

Schritt 4: Mit Modifikatoren erweitern

Der letzte Schritt besteht darin, Ihre Komponente/Ihr Muster mit Modifikatoren zu erweitern. Modifikatoren sind im Wesentlichen Variationen, die den grundlegenden Block und die untergeordneten Elemente erweitern und nach Bedarf erstellt werden können.

Beispiel für eine HTML-Modifikatorklasse

<div class="block block—modifier">
  <div class="block__element">…</div>
  <div class="block__another-element">…</div>
</div>

Beispiel für CSS-Modifikation

.block—modifier {
  border-top: 3px solid red;
}

.block—modifier .block__element {
  background: grey;
}

Beispiele

Nachdem wir uns die grundlegenden Schritte zur Erstellung erweiterbarer Komponenten und Muster angesehen haben, ist es an der Zeit, einige Beispiele zu untersuchen. Wir beginnen mit einer relativ einfachen Komponente und wie sie erweitert werden kann, um eine Vielzahl von Szenarien abzudecken, und dann betrachten wir ein etwas komplexeres Muster.

Über Komponenten

Im Folgenden finden Sie eine Demo mehrerer gängiger Komponenten mit Variationen. Jede Komponente besteht aus einem übergeordneten Block und Modifikatoren, die den Stil des Blocks erweitern. Dies ermöglicht die schnelle Erstellung von Variationen und gibt Ihnen die Flexibilität, Komponenten schnell zu iterieren und an jede Situation in Ihrer Benutzeroberfläche anzupassen.

Beispiel für gängige Komponenten

Sehen Sie den Pen Gemeinsame erweiterbare Komponenten von Jon Yablonski (@jonyablonski) auf CodePen.

Komponenten sollten naturgemäß relativ einfach sein, da sie keine untergeordneten Elemente enthalten. Nun schauen wir uns etwas Komplexeres an.

Über Muster

Ein Medienmuster ist ein Objekt, das aus einem Medienelement (dies kann ein Bild oder Video sein) und zugehörigem Inhalt (in der Regel in Form von Text) besteht. Sie sind vielleicht mit einer Variante des Medienmusters vertraut, die als „Media Object“ oder „Flag Object“ bekannt ist, auf die wir gleich eingehen werden. Dieses Muster ist ein großartiges Beispiel dafür, wie die Entwicklung mit Blick auf Erweiterbarkeit endlose Flexibilität bietet.

Standard-Medienmuster

Wir beginnen mit unserem Standardmuster, also damit, wie es ohne Modifikatoren angezeigt wird. Ich habe hier einige Annahmen getroffen, indem ich ein <article>-Tag verwendet habe, um semantischere Informationen bereitzustellen, aber dies kann durch jedes beliebige Tag ersetzt werden. Die Kernstile unseres Medienmusters sind

  1. Ein Flex-Container, dessen Kinder nicht umgebrochen werden
  2. Ein bisschen Rand

Dies sind Stile, die alle Medienmuster erben werden. Darüber hinaus wird jedes Medienmuster das Medienelement (in diesem Fall ein Bild) und den Medienkörper enthalten, der aus einem Titel und einer Definitionsliste besteht.

Sehen Sie den Pen Standard-Medienmuster von Jon Yablonski (@jonyablonski) auf CodePen.

Medienkartenmuster

Während diese Standardvariante unseres Medienmusters unter Umständen ausreichend sein mag, wird es viele andere geben, bei denen Sie sein Aussehen drastisch ändern möchten. Der nächste Schritt besteht darin, Variationen zu identifizieren, die es unserem Muster ermöglichen, sich an verschiedene Situationen anzupassen. Beginnen wir mit einer Variation, die keine große Abweichung vom Standardaussehen darstellt – einer Kartenvariante. Die Prämisse ist, dass sich nur sehr wenig an unserer Struktur ändern muss und wir das Aussehen unseres Musters ändern können, indem wir einfach eine Modifikatorklasse zum übergeordneten Block hinzufügen.

Sehen Sie den Pen Medienkartenmuster von Jon Yablonski (@jonyablonski) auf CodePen.

Media-Objektmuster

Nehmen wir an, ich habe später festgestellt, dass ich ein Muster benötige, bei dem das Bild und der Text nebeneinander angezeigt werden, wenn genügend Platz vorhanden ist. Dies ist ein Muster, das allgemein als „Medienobjekt“ bekannt ist. Um es zu erstellen, können wir einfach das bereits vorhandene Medienmuster erweitern, um redundanten Code zu minimieren.

Sehen Sie den Pen Media-Objektmuster von Jon Yablonski (@jonyablonski) auf CodePen.

Media Slat-Muster

Lassen Sie uns die Dinge noch etwas weiter treiben mit einer Variante, die wirklich auf die Probe gestellt wird. Die bisher definierten Varianten decken ziemlich gut alle meine Designbedürfnisse ab, aber ich brauche noch eine mit etwas mehr Wirkung. Lassen Sie uns eine Variante erstellen, die sich über die gesamte Fensterbreite erstreckt, wobei der Körper die Hälfte und das Bild die andere Hälfte einnimmt. Darüber hinaus möchte ich sicherstellen, dass der Inhalt des Körpers mit dem anderen Inhalt auf der Seite ausgerichtet ist. Wir nennen diese Variante „Media Slat“.

Sehen Sie den Pen Media Slat-Muster von Jon Yablonski (@jonyablonski) auf CodePen.

Jetzt haben wir mehrere Varianten unseres Medienmusters: die Standardvariante, die Kartenvariante, die Objektvariante und schließlich die Slat-Variante. Diese Varianten unseres Musters sind unter verschiedenen Umständen nützlich und alle nutzen die gleiche zugrunde liegende Codebasis! Das Tolle daran ist, dass jede Änderung an unserem Muster alle Muster beeinflusst, sodass jede Instanz dieses Musters synchron und konsistent bleibt.

Fazit

Wir haben abgedeckt, warum erweiterbare Komponenten und Muster beim Erstellen von Benutzeroberflächen besser sind, mit Fokus auf Flexibilität und Wartbarkeit. Und um dies zu veranschaulichen, haben wir die Schritte zur Erstellung einiger erweiterbarer Komponenten behandelt. Die Vorteile der Erstellung von Benutzeroberflächen auf diese Weise werden sich sofort zeigen, da Sie weniger Zeit mit Refactoring aufgrund unerwarteter Designänderungen oder -ergänzungen verbringen und Ihre Styling-Elemente, aus denen diese Komponenten bestehen, einfacher zu warten sind.