Custom Elements – individuelle HTML-Tags

Individuelle eigene HTML Tags

Custom Elements erweitern das Standard-HTML um eigene individuelle HTML-Elemente und übernehmen Aufgaben von der Darstellung im Browser bis hin zu Verhalten (Javascript), die es in den vorgefertigten HTML-Elementen so nicht gibt.

23-02-02 SITEMAP

Eigene HTML-Elemente

Eigene HTML-Tags bringen ein modulares HTML-Markup ins Spiel, das an weiteren Stellen in einer anderen Umgebung wiederverwendbar ist.

Werfen wir einen Blick hinter die Kulissen einer WordPress-Seite: Das HTML-Markup besteht zu 80% aus div-Tags, die mehrfach ineinander verschachtelt sind, und mit einem Dutzend CSS-Klassen gestylt sind. Seit Jahr und Tag sind div-Tags die Arbeitspferde im HTML-Markup.

<div class="pb-4">
	<div class="bg-white border rounded-5">
		<div class="p-4 w-100" style="border-radius: .5rem .5rem 0 0;">
			<div class="row d-flex justify-content-center">
				<div class="col-md-8 col-lg-6">
					<div class="card shadow-0 border" style="background-color: #f0f2f5;">
						<div class="card-body p-4">
							<div class="form-outline mb-4">
								<input type="text" id="addANote" class="form-control" placeholder="">
								<label class="form-label" for="addANote" style="margin-left: 0px;">+ Wer kommt mit? Bitte anmelden!</label> 
								<div class="form-notch">
									<div class="form-notch-leading" style="width: 9px;"></div>
									<div class="form-notch-middle" style="width: 80.8px;"></div>
									<div class="form-notch-trailing"></div>
								</div>
							</div>
							<div class="card mb-4">
								<div class="card-body">
									<p>Wir kommen immer gerne mit!</p>
									<div class="d-flex justify-content-between">
										<div class="d-flex flex-row align-items-center">
											<img src="img/avatar-05.webp" width="25" height="25" alt="avatar-05"> 
											<p class="small mb-0 ms-2">Anne</p>
										</div>
										<div class="d-flex flex-row align-items-center">
											<p class="small text-muted mb-0">Like?</p>
											<i class="far fa-thumbs-up mx-2 fa-xs text-black" style="margin-top: -0.16rem;"></i> 
											<p class="small text-muted mb-0">3</p>
										</div>
									</div>
								</div>
							</div>
							<div class="card mb-4">
								<div class="card-body">
									<p>Klar sind wir alle dabei!</p>
									<div class="d-flex justify-content-between">
										<div class="d-flex flex-row align-items-center">
											<img src="img/avatar-04.webp" width="25" height="25" alt="avatar-05"> 
											<p class="small mb-0 ms-2">Otto Hufinger</p>
										</div>
										<div class="d-flex flex-row align-items-center">
											<p class="small text-muted mb-0">Like?</p>
											<i class="far fa-thumbs-up mx-2 fa-xs text-black" style="margin-top: -0.16rem;"></i> 
											<p class="small text-muted mb-0">4</p>
										</div>
									</div>
								</div>
							</div>
							<div class="card mb-4">
								<div class="card-body">
									<p>Kind No 1 hat leider Schnupfen
									</p>
									<div class="d-flex justify-content-between">
										<div class="d-flex flex-row align-items-center">
											<img src="img/avatar-03.webp" width="25" height="25" alt="avatar-05"> 
											<p class="small mb-0 ms-2">Greta</p>
										</div>
										<div class="d-flex flex-row align-items-center text-primary">
											<p class="small mb-0">Like?</p>
											<i class="fas fa-thumbs-up mx-2 fa-xs" style="margin-top: -0.16rem;"></i> 
											<p class="small mb-0">2</p>
										</div>
									</div>
								</div>
							</div>
							<div class="card">
								<div class="card-body">
									<p>Neue Schuhe!
									</p>
									<div class="d-flex justify-content-between">
										<div class="d-flex flex-row align-items-center">
											<img src="img/avatar-02.webp" width="25" height="25" alt="avatar-05"> 
											<p class="small mb-0 ms-2">Emma</p>
										</div>
										<div class="d-flex flex-row align-items-center">
											<p class="small text-muted mb-0">Like?</p>
											<i class="far fa-thumbs-up ms-2 fa-xs text-black" style="margin-top: -0.16rem;"></i> 
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

Erst HTML5 brachte das Konzept der Custom Elements, die im Grunde genommen simpel sind: Alle HTML-Tags mit einem Bindestrich sind Custom Elements, denen die Browser keinerlei Stil und Verhalten mitgeben.

Die individuellen HTML-Elemente kapseln die Darstellung und das Verhalten vom Rest des Markups, den CSS-Regeln und Scripten der Seite ab.

<block-card>
	…
</block-card>

Die Definition für Custom Elements sagt ganz einfach: Alle HTML-Elemente, die mit einem Bindestrich notiert werden, sind Custom Elements. Sie sind valide HTML-Syntax und brauchen keine weiteren Definitionen und keine spezielle DTD. Der HTML-Standard definiert zwei Typen von Custom Elements:

  • Autonomous Custom Elements erben keine Eigenschaften von HTML-Standard-Elementen.
  • Customized Elements erben von HTML-Elementen und stellen eine angepasste Version eines existierenden HTML-Elements dar.

Custom Elements sind nicht gleichbedeutend mit Web Components. Web Components sind drei Technologien, die unabhängig voneinander genutzt werden können: Custom Elements, Shadow DOM und HTML Templates. Sie erzeugen wiederverwendbare Komponenten mit Javascript, HTML und CSS – ohne Einsatz von Libraries wie React und Bootstrap.

Globale Variablen

Wer programmiert, kennt das Problem von globalen Variablen: Sie sind immer in Gefahr, an der falschen Stelle überschrieben zu werden. Programmiersprachen arbeiten mit Funktionen, Objekten und Klassen und ihren lokalen Variablen dagegen an.

In CSS besteht ebenfalls die Gefahr, dass Regeln an anderer Stelle beeinflußt und überschrieben werden. Wir können zwar anhand von Klassen und Selektoren diese Gefahr dämpfen, aber vollständig abkapseln können wir HTML-Elemente gegen die Beeinflussung nicht. CSS hat keine Module.

So wird das HTML ul-Element oft für das Menü der Seite benutzt. Dafür müssen dem ul-Element Eigenschaften abgewöhnt werden:

  • Das Einrücken der Liste
  • Der Listenpunkt vor jedem li-Element

Gleichzeitig muss das HTML-Markup vor dem Einfluss von CSS geschützt werden, das an anderen Stellen für Listen zum Einsatz kommt.

Komplexes HTML

Neben einfachen Strukturen wie einem Navigations-Menü für die Seite werden zusammengesetzte Elemente an vielen Stellen verwendet, z.B. drei Spalten in einem Block, wie sie vom WordPress-Gutenberg-Editor angelegt werden oder die Beschreibung eines Produkts mit dem Produktbild, Preis, Menge, Kurzbeschreibung, Verfügbarkeit.

film-card {
	counter-increment: chartnum;
	display:flex;
}
<block-card>
	<film-card>
		…
	<film-card>
<block-card>

und mit eigenen Attributen für Variationen

<block-card start-num="6" lead-color="blue">
	<film-card>
		…
	<film-card>
<block-card>

Mann unter Feuer

Der abgewrackte Navy-Soldat Creasy übernimmt einen Bodyguard-Job in Mexiko.

Peanuts Der Film

Charlie Brown, Snoopy und Lucy haben ihren ersten Auftritt als computeranimierte Helden.

Stargate Origins

1930 kämpfen Professor Langford und seine Tochter noch mit den Rätseln des Artefakts.

DÉJÀ VU

Terroristen sprengen eine Fähre – Carlin (Denzel Washington) unternimmt einen Zeitsprung.

Känguru-Chroniken

Kleinkünstler Marc-Uwe (Dimitrj Schaad) und das antikapitalistische Känguru.

Stargate Origins

1930 kämpfen Professor Langford und seine Tochter noch mit den Rätseln des Artefakts.

Custom Elements umgehen die Probleme, die durch mehrfach innerhalb einer Seite genutzte komplexe Strukturen entstehen, wie z.B. gleiche Klassennamen oder doppelte IDs.

Custom Elements Syntax

Der Name eines Custom Elements muss einen Bindestrich enthalten, z.B. cosmetic-product, extended-sidebar, top-header. Zusammengesetzte Tag-Namen wie cosmeticProduct, blueLargeButton und reiseBeschreibung hingegen sind invalid – nicht korrekt. Jedes Custom Element muss aus einem öffnenden und einem schließenden Tag bestehen. Selbst-schließende Elemente wie das img-Tag sind in Custom Elements nicht erlaubt. Durch den Bindestrich unterscheidet der HTML-Parser Custom Elements von regulären HTML-Tags.

Jedes Custom Element kann nur einmal definiert werden, ansonsten kommt es zu einer DOM Exception.

Weitere Unterschied zu einem normalen HTML-Tag gibt es nicht. Ein Custom Element kann dynamisch von Javascript erzeugt und mehrfach in einer Seite verwendet werden, Event Listener können an das Custom Element gebunden werden.

Custom Elements v1: Reusable Web Components

Vorgehen

Für ein spezielles Verhalten eines Custom Elements ist Javascript zuständig.

  • Anlegen einer Javascript class, um die Funktionalität der Web Component festzulegen
  • Definition des Custom Elements mit customElement.define ('cosmetic-product',CosmeticProduct)
  • Evtl. mit Element.attachShadow () ein Shadow DOM hinzufügen
class block-card extends HTMLElement { … }
window.customElements.define('block-card', BlockCard);

Alternativ 

window.customElements.define('block-card', class extends HTMLElement { … });