Blog-Headerbild
Ferdinand Malcher
 

Goodbye, ngClass und ngStyle!

27.11.2024

Voraussichtlich in der Version 19.1 von Angular werden die Direktiven ngClass und ngStyle als deprecated markiert. In diesem Blogpost erläutern wir die Hintergründe und die Migration.

tl;dr

Die Direktiven ngClass und ngStyle werden als deprecated markiert, siehe Pull Request #58860. Sie können in der Regel nahtlos mit Property Bindings auf die nativen Propertys class und style ersetzt werden:

<!-- VORHER -->
<div [ngClass]="myClass"></div>
<div [ngClass]="myClasses"></div>
<div [ngClass]="{ foo: isFoo() }"></div>
<div [ngStyle]="{ color: 'red' }"></div>

<!-- NACHHER -->
<div [class]="myClass"></div>
<div [class]="myClasses"></div>
<div [class]="{ foo: isFoo() }"></div>
<div [style]="{ color: 'red' }"></div>

Die Direktiven ngClass und ngStyle

Angular bietet seit jeher die beiden Attributdirektiven ngClass und ngStyle an. Damit können wir CSS-Klassen bzw. CSS-Stile auf ein DOM-Element im Template anwenden.

Die Attribute class und style ermöglichen dies in HTML grundsätzlich mit statischen Werten:

<h1 class="headline">Headline</h1>
<p style="font-size: 1em"></p>

Sollen CSS-Klassen und Stile dynamisch angewendet werden, z. B. aus Propertys der Komponentenklasse, helfen uns die beiden mitgelieferten Direktiven von Angular. In der letzten Zeile des folgenden Beispiels ist zu sehen, wie mehrere CSS-Klassen anhand von Bedingungen angewendet werden: Die Klasse danger wird angewendet, wenn isError() den Wert true zurückgibt.

<h1 [ngClass]="myHeadlineClass">Headline</h1>
<p [ngStyle]="{ 'font-size': myFontSize }"></p>

<div class="alert" [ngClass]="{ danger: isError(), success: !isError() }"></div>

Diese Direktiven werden mit Angular 19.1 als deprecated markiert und in einer späteren Version entfernt. Was bedeutet das für die Templates unserer Angular-Anwendungen?

Die Lösung: Property Bindings mit [class] und [style]

Mit Property Bindings können wir grundsätzlich auch alle nativen Propertys von DOM-Elementen beschreiben, darunter die Propertys class und style. Diese Schreibweise ist schon immer möglich und ist in einer Sonderform als Class Binding bzw. Style Binding bekannt. Damit können wir einzelne Klassen abhängig von einer Bedingung anwenden und Werte für CSS-Propertys schreiben:

<p [style.font-size]="myFontSize"></p>

<div class="alert" [class.danger]="isError()" [class.success]="!isError()"></div>

Auch ohne diese Sonderform können wir class und style direkt mithilfe von Property Bindings abbilden. Dabei funktionieren verschiedene Schreibweisen, die bisher auch mit ngClass und ngStyle möglich waren: als String, als Array von Strings oder als Objekt für Entscheidungen.

<h1 [class]="myHeadlineClass">Headline</h1>
<h2 [class]="['foo', 'bar']">Headline mit mehreren Klassen</h2>
<p [style]="{ 'font-size': myFontSize }"></p>

<div [class]="{ alert: true, danger: isError(), success: !isError() }"></div>

In den meisten Fällen können die Direktiven ngClass und ngStyle also nahtlos durch Property Bindings mit class und style ersetzt werden. Diese Migration ist mithilfe von Suchen & Ersetzen im Editor unkompliziert möglich. Außerdem wird Angular wahrscheinlich ein Migrationsskript anbieten, um die Templates umzustellen. Bitte vergessen Sie nicht, auch die Imports der Direktiven in der Komponentenklasse zu entfernen.

Warum?

Da mit den nativen Mitteln von Browser und Angular alle notwendigen Bindings erstellt werden können, ist es nicht mehr zwingend notwendig, die Direktiven zu verwenden. Zusätzliche Bausteine erschweren es nicht nur, Angular zu lernen, sondern: Die Größe des ausgelieferten JavaScript-Bundles wächst mit jeder zusätzlichen Direktive.

Wir haben die Templates unserer Website migriert und auf ngClass und ngStyle verzichtet. Die Ersparnis bei der Bundle-Größe betrug in diesem Szenario etwa 5 KB.

Limitationen

Obwohl [class] und [style] ein direkter Ersatz für die Direktiven sind, funktionieren einige wenige Details anders:

  • Es kann kein Set übergeben werden. Es wird empfohlen, stattdessen ein Array zu verwenden.
  • In der Objektschreibweise konnte ein Schlüssel auch mehrere Klassen oder CSS-Propertys beinhalten: [ngClass]="{ 'foo bar': isFoo() }". Diese Schreibweise ist mit dem nativen Binding nicht mehr möglich. Es wird empfohlen, die Klassen einzeln aufzuführen: [class]="{ foo: isFoo(), bar: isFoo() }"

Fazit

Die Direktiven ngClass und ngStyle hatten lange ihre Berechtigung und waren ein wichtiges Werkzeug bei der Notation der HTML-Templates. Inzwischen unterstützt Angular fast alle Schreibweisen aber auch mit Property Bindings auf die nativen DOM-Propertys class und style. Wir empfehlen Ihnen also, auf die Direktiven zu verzichten und Property Bindings zu verwenden. Wir begrüßen diesen Schritt sehr, die API-Oberfläche des Frameworks weiter zu verkleinern und unnötige Teile zu entfernen.

Laut dem Pull Request wird es noch eine Migration durch die Angular CLI geben, um Templates dort anzupassen, wo es automatisch möglich ist. Es ist also nicht notwendig, die bestehenden Direktiven sofort manuell zu ändern. Gleichzeitig empfehlen wir aber, bei neuem Code sofort auf die moderne Schreibweise umzusteigen.


Titelbild: generiert mit Adobe Firefly

Zurück | Back
Suggestions? Feedback? Bugs? Please fork/edit this page on Github .