Bessere Semantik: Eigene Tags nutzen mit HTML5 Custom Elements

Semantik hat mir bei HTML schon immer gefallen,
<div>-Suppen vermeide ich wann immer möglich und schöpfe gerne die Markup-Möglichkeiten aus. Dementsprechend hab ich mich auch größtenteils über die neuen Elemente von HTML5 gefreut. Noch im Fluss, aber schon weit gediegen, sind die Custom Elements der Web Components – also die Nutzung von eigens definierten Tags, ähnlich wie man es von XML-Dokumenten kennt. Eine Ausrede à la „es gab kein passendes Tag“ ist damit also passé.

Die Regel für Custom Elements ist einfach: sie müssen einen Bindestrich beinhalten. Das ist vor allem deshalb sinnvoll um eine Erweiterung der HTML-Standardelemente in Zukunft zu ermöglichen ohne dass sich Custom Elements mit ihnen überschneiden. Beispielsweise ist <mein-tag> valide, jedoch <meintag> nicht.

Die Nutzung

Beim Schreiben von Code kann man einfach die Custom Elements nutzen wie die bekannten Tags des HTML-Standards. Jedoch gelten diese erstmal als HTMLUnknownElement – sind also nicht zu unterscheiden von Elementen bei denen man sich einfach nur vertippt hat. Damit die selbst definierten Tags registrierte Elemente des Dokuments werden braucht es etwas JavaScript:

document.registerElement("mein-tag");

Schreibt man die Custom Elements eh ausschließlich für eine Web-App kann man seine Tags im entsprechenden Namensraum registrieren (kann man natürlich auch so):

var meineWebApp = {};
meineWebApp.meinTag = document.registerElement("mein-tag");

Steht ein Tag schon im HTML-Dokument (ist also deklariert) und wird erst durch JavaScript registriert (und nicht nur durch das JavaScript ins DOM geschrieben) gilt es solange noch als „Unresolved Element“ und kann per CSS mittels der Pseudo-Klasse „unresolved“ angesprochen und z.B. ausgeblendet werden:

mein-tag:unresolved {
  display: none;
}

JavaScript-Methoden und -Eigenschaften definieren

Nun kann man seine Custom Elements auch mit Funktionalität ausstatten, sodass einzelne Werte zurückgegeben werden können oder Funktionen ausgeführt werden.

var meinTag = document.registerElement('mein-tag', {
  prototype: Object.create(HTMLElement.prototype, {
    foo: {
      get: function() { 
        return "bar";
      }
    },
    baz: {
      value: function() {
        alert("Funktion baz() des Custom Elements wurde aufgerufen");
      }
    }
  })
});

Callbacks

Man kann für sein Custom Element auch Funktionen für vier Callbacks definieren:

  • createdCallback
    Instanz des Elements wird erstellt
  • attachedCallback
    Instanz wird ins DOM eingefügt
  • detachedCallback
    Instanz wird aus dem DOM entfernt
  • attributeChangedCallback(attrName,oldVal,newVal)
    Attribut wurde hinzugefügt/entfernt/geändert
var prot = Object.create(HTMLElement.prototype);

prot.createdCallback = function() {
  this.addEventListener("click", function(event) {
    ...
  });
};

prot.detachedCallback = function() {
  this.removeEventListener("click", function(event) {
    ...
  });
};

var meinTag = document.registerElement("mein-tag", { prototype: prot });

Custom Elements für Fortgeschrittene

Man kann sich natürlich nicht nur einfache Custom Elemente für mehr Semantik definieren sondern auch welche mit richtig viel Funktionalität. Denken wir z.B. an das HTML5-Tag <video> wissen wir, dass dieses noch mehr Tags beinhaltet. Man kann auch für Custom Elements natürlich weiteres HTML darin verschachteln, auch das können wiederum Custom Elements sein, die eigene Methoden und Eigenschaften haben. Diese Elemente wiederum kann man – statt sie direkt als Kind-Elemente in das Custom Element zu legen – dort im Shadow DOM ablegen.
Kreiert man sich nun mit JavaScript das Haupt-Element, darin die Custom Elements im Shadow DOM und definiert seine JS-Methoden und -Eigenschaften kann man sich damit immer wieder mittels des new-Operators weitere Instanzen erstellen und ins DOM einfügen.

Wirklich hilfreich für die Semantik?

Wer Custom Elements nur für bessere Semantik im HTML-Dokument nutzen möchte muss immer damit rechnen ein invalides Dokument auszuliefern, denn es braucht immer JavaScript zum Registrieren des neuen Elements. Auch alte Browser, die registerElement() nicht kennen verstehen trotz JavaScript das Dokument nicht richtig und behandeln die Custom Elements als Tags vom Typ HTMLUnknownElement.
Zum Testen der Browser-Kompatibilität eignet sich folgendes JavaScript:


if ('registerElement' in document) {
  ...
}

Veröffentlicht von

Hilko

2006 machte ich mein Hobby zum Beruf, startete mit einer Ausbildung zum Mediengestalter und arbeite inzwischen in Hannover als Frontend Web-Developer. Neben der Leidenschaft für semantisches Markup und den Möglichkeiten der aktuellen Frontend-Techniken, interessiere ich mich für das Reisen, fremde Kulturen und die Kunst der Fotografie.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.