Eine Angular-Komponente ist nicht nur für HTML und TypeScript verantwortlich, sondern bringt auch ihre eigenen CSS-Styles mit. Das Besondere an Angular ist das eingebaute “Style Scoping” (CSS-Kapselung): Styles, die für eine Komponente geschrieben werden, gelten standardmäßig nur für diese eine Komponente und “leaken” nicht in den Rest der Anwendung. In diesem Artikel lernst du die verschiedenen Einbindungsmethoden und die Encapsulation-Modi im Detail kennen.

Styles definieren

Du hast im @Component-Dekorator zwei Möglichkeiten, Styles an eine Komponente zu binden. Welche Variante du wählst, hängt meist von der Größe des CSS-Codes ab. Angular unterstützt nativ normales CSS, aber auch Präprozessoren wie Sass (.scss, .sass) oder Less (.less).

Inline Styles

Für sehr kleine, übersichtliche Styling-Anpassungen kannst du das styles-Feld nutzen:

TypeScript profile.component.ts
import { Component } from '@angular/core';

@Component({
    selector: 'app-profile-photo',
    template: `<img src="profile-photo.jpg" alt="Profile" />`,
    styles: `
        img {
            border-radius: 50%;
            width: 100px;
            height: 100px;
        }
    `,
    standalone: true
})
export class ProfilePhotoComponent {}

Externe Dateien

Sobald dein CSS komplexer wird, ist es Best Practice, es in eine separate Datei auszulagern und über styleUrl (bzw. styleUrls bei älteren Angular-Versionen) einzubinden:

TypeScript profile.component.ts
@Component({
    selector: 'app-profile-photo',
    templateUrl: './profile-photo.html',
    styleUrl: './profile-photo.scss',
    standalone: true
})
export class ProfilePhotoComponent {}

View Encapsulation (Style Scoping)

Jede Komponente in Angular besitzt eine encapsulation-Eigenschaft, die festlegt, wie streng die CSS-Regeln der Komponente vom Rest der Applikation isoliert werden. Angular bietet hierfür vier Modi an:

1. ViewEncapsulation.Emulated (Standard)

Dies ist der Default-Modus. Angular emuliert die Isolation von Styles. Es generiert beim Kompilieren einzigartige HTML-Attribute (z.B. _ngcontent-abc-1) für jedes Element im Template der Komponente und hängt dieses Attribut automatisch an jeden CSS-Selektor der Komponente an (z.B. img[_ngcontent-abc-1] { ... }).

  • Ergebnis: Deine Styles betreffen nur das eigene HTML-Template. Globale Styles der Anwendung können jedoch weiterhin die Elemente in dieser Komponente beeinflussen.

2. ViewEncapsulation.None

Schaltet die Isolation komplett ab. Alle in der Komponente definierten Styles werden global in der Anwendung injiziert.

  • Ergebnis: Ein h1 { color: red; } in dieser Komponente färbt alle h1-Elemente in der gesamten App rot, sobald die Komponente geladen wird. Nutze dies nur äußerst sparsam!

3. ViewEncapsulation.ShadowDom

Dieser Modus nutzt den echten nativen Browser-Standard Shadow DOM API. Es erstellt einen abgetrennten Shadow-Root-Baum.

  • Ergebnis: Perfekte Isolation. Styles entweichen nicht nach außen, aber globale Styles (wie z.B. Bootstrap oder Tailwind) dringen auch nicht mehr nach innen. Es ändert außerdem die Funktionsweise von DOM-Events und <slot> Elementen stark.

4. ViewEncapsulation.ExperimentalIsolatedShadowDom

Eine experimentelle Erweiterung von ShadowDom, die noch strikter garantiert, dass wirklich absolut keine globalen Styles in die Komponente leaken und umgekehrt.

TypeScript Encapsulation ändern
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
    selector: 'app-global-banner',
    template: `<h1>Ich bin ein Banner</h1>`,
    styles: `h1 { text-transform: uppercase; }`,
    encapsulation: ViewEncapsulation.None, // Styles werden global!
    standalone: true
})
export class GlobalBannerComponent {}

Spezielle CSS Selektoren

Da Komponenten gekapselt sind, bietet Angular (im Standard-Modus Emulated) einige spezielle CSS-Pseudo-Klassen, um mit den Komponentengrenzen umzugehen:

:host

Mit :host kannst du das Element stylen, das die Komponente “hostet” (also das Tag, das dem Komponenten-Selektor entspricht). Ohne :host hättest du aus dem eigenen SCSS der Komponente keinen Zugriff darauf, da es sich streng genommen außerhalb des Komponenten-Templates befindet.

SCSS style.scss
:host {
    display: block; // Angular Host-Elemente sind standardmäßig inline!
    border: 1px solid #ccc;
    padding: 1rem;
}

:host(.active) {
    // Nur wenn das Host-Element die Klasse "active" hat
    background-color: lightblue;
}

::ng-deep (Veraltet / Deprecated)

Ursprünglich genutzt, um die Emulated-Encapsulation zu “durchbrechen”. Ein Selektor wie ::ng-deep p sorgt dafür, dass alle <p> Elemente in der gesamten Anwendung gestylt werden (global). Ein Selektor wie :host ::ng-deep p zwingt Angular, die Styles auf das eigene Template und alle Child-Komponenten tief verschachtelt anzuwenden.

Häufige Stolperfallen

::ng-deep leakt ins Globale

Wenn Entwickler ::ng-deep .my-class ohne :host davor schreiben, wird der Style global angewendet, sobald die Komponente einmalig geladen wurde. Dies führt zu “Ghost-Bugs” auf komplett anderen Seiten der App.

Host-Elemente sind immer display: inline

Custom HTML Tags (<app-meine-komponente>) sind nach Browser-Standard immer Inline-Elemente. Sie haben standardmäßig keine Breite oder Höhe. Du musst oft im CSS explizit :host { display: block; } (oder flex) definieren, damit Abstände (Margins/Paddings) korrekt funktionieren.

Tailwind CSS & Encapsulation

Wenn du Tailwind in einer Komponente verwendest, gelten die Tailwind-Klassen nur im eigenen HTML. Wenn du in einer app-button Komponente versuchst, einer eingebetteten Child-Komponente von außen via class="bg-red-500" Farbe zu geben, funktioniert das oft nicht, da das Child seine eigenen Encapsulated-Styles hat, die möglicherweise eine höhere Spezifität besitzen.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Komponenten

Zur Übersicht