Wie werden untergeordnete Komponenten aus der CSS-Datei der übergeordneten Komponente formatiert?

264

Ich habe eine übergeordnete Komponente:

<parent></parent>

Und ich möchte diese Gruppe mit untergeordneten Komponenten füllen:

<parent>
  <child></child>
  <child></child>
  <child></child>
</parent>

Übergeordnete Vorlage:

<div class="parent">
  <!-- Children goes here -->
  <ng-content></ng-content>
</div>

Untergeordnete Vorlage:

<div class="child">Test</div>

Schon seit parent und childzwei separate Komponenten sind, sind ihre Stile an ihren eigenen Bereich gebunden.

In meiner übergeordneten Komponente habe ich versucht:

.parent .child {
  // Styles for child
}

Aber die .child Stile werden jedoch nicht auf die childKomponenten angewendet .

Ich habe versucht styleUrls, das parentStylesheet des Stylesheets in die childKomponente aufzunehmen, um das Scope-Problem zu lösen:

// child.component.ts
styleUrls: [
  './parent.component.css',
  './child.component.css',
]

Aber das hat nicht geholfen, auch in die andere Richtung versucht, indem das childStylesheet abgerufen wurde, parentaber das hat auch nicht geholfen.

Wie formatieren Sie untergeordnete Komponenten, die in einer übergeordneten Komponente enthalten sind?

Chrillewoodz
quelle
1
Siehe auch stackoverflow.com/questions/34542143/…
Günter Zöchbauer
Sehen Sie in meiner Antwort einen völlig paradigmenfreundlichen, trickfreien Weg .
Alexander Abakumov

Antworten:

242

Update - Neuester Weg

Tu es nicht, wenn du es vermeiden kannst. Wie Devon Sans in den Kommentaren betont: Diese Funktion wird höchstwahrscheinlich veraltet sein.

Update - Neuerer Weg

Ab Angular 4.3.0 waren alle Piercing-CSS-Kombinatoren veraltet. Das Angular-Team hat einen neuen Kombinator eingeführt ::ng-deep (er befindet sich noch auf experimentellem Niveau und nicht auf dem vollständigen und endgültigen Weg), wie unten gezeigt.

DEMO: https://plnkr.co/edit/RBJIszu14o4svHLQt563?p=preview

styles: [
    `
     :host { color: red; }

     :host ::ng-deep parent {
       color:blue;
     }
     :host ::ng-deep child{
       color:orange;
     }
     :host ::ng-deep child.class1 {
       color:yellow;
     }
     :host ::ng-deep child.class2{
       color:pink;
     }
    `
],



template: `
      Angular2                                //red
      <parent>                                //blue
          <child></child>                     //orange
          <child class="class1"></child>      //yellow
          <child class="class2"></child>      //pink
      </parent>      
    `


Alter Weg

Sie können encapsulation modeund / oder verwendenpiercing CSS combinators >>>, /deep/ and ::shadow

Arbeitsbeispiel: http://plnkr.co/edit/1RBDGQ?p=preview

styles: [
    `
     :host { color: red; }
     :host >>> parent {
       color:blue;
     }
     :host >>> child{
       color:orange;
     }
     :host >>> child.class1 {
       color:yellow;
     }
     :host >>> child.class2{
       color:pink;
     }
    `
    ],

template: `
  Angular2                                //red
  <parent>                                //blue
      <child></child>                     //orange
      <child class="class1"></child>      //yellow
      <child class="class2"></child>      //pink
  </parent>      
`
Mikronyken
quelle
3
Piercing CSS-Kombinatoren sind in Chrome jedoch veraltet
Robin-Hoodie
22
Das eckige Team plant, die Unterstützung von :: ng-deep ebenfalls einzustellen. Aus ihren Dokumenten: "Der Schatten-durchdringende Nachkommen-Kombinator ist veraltet und die Unterstützung wird von den wichtigsten Browsern und Tools entfernt. Daher planen wir, die Unterstützung in Angular (für alle 3 von / deep /, >>> und :: ng-) einzustellen. deep). Bis dahin sollte :: ng-deep für eine breitere Kompatibilität mit den Tools bevorzugt werden. " angle.io/guide/component-styles#deprecated-deep--and-ng-deep .
Devon Sams
5
Solange dies als akzeptierte Antwort bleibt, werden die Menschen irregeführt. :: ng-deep sollte im obigen Kommentar nicht als @ DevonSams-Punkte verwendet werden.
Kostas Siabanis
1
::ng-deepist jetzt veraltet , ich empfehle nicht, es in zukünftigen Anwendungen zu verwenden
Wilt
11
Etwas zu verwerfen, ohne eine Alternative anzubieten, ist wahrscheinlich nicht die beste Lösung.
Tehlivi
56

UPDATE 3:

::ng-deepist ebenfalls veraltet, was bedeutet, dass Sie dies überhaupt nicht mehr tun sollten. Es ist unklar, wie sich dies auf Dinge auswirkt, bei denen Sie Stile in untergeordneten Komponenten von einer übergeordneten Komponente überschreiben müssen. Für mich ist es seltsam, wenn dies vollständig entfernt wird, denn wie würde sich dies auf Dinge als Bibliotheken auswirken, bei denen Sie Stile in einer Bibliothekskomponente überschreiben müssen?

Kommentar, wenn Sie einen Einblick in diese haben.

UPDATE 2:

Da /deep/und alle anderen Schattenpiercing-Selektoren sind jetzt veraltet. Angular Drop ::ng-deep, der stattdessen für eine breitere Kompatibilität verwendet werden sollte.

AKTUALISIEREN:

Wenn Sie Angular-CLI verwenden, müssen Sie /deep/anstelle von verwenden, >>>sonst funktioniert es nicht.

ORIGINAL:

Nachdem ich auf Angular2s Github-Seite gegangen war und eine zufällige Suche nach "Stil" durchgeführt hatte, fand ich folgende Frage: Angular 2 - innerHTML- Stil

Welches sagte, um etwas zu verwenden, das hinzugefügt wurde 2.0.0-beta.10, die >>>und ::shadowSelektoren.

(>>>) (und das Äquivalent / deep /) und :: shadow wurden in 2.0.0-beta.10 hinzugefügt. Sie ähneln den Schatten-DOM-CSS-Kombinatoren (die veraltet sind) und funktionieren nur mit der Kapselung: ViewEncapsulation.Emulated, die Standardeinstellung in Angular2. Sie funktionieren wahrscheinlich auch mit ViewEncapsulation.None, werden dann aber nur ignoriert, weil sie nicht erforderlich sind. Diese Kombinatoren sind nur eine Zwischenlösung, bis erweiterte Funktionen für das komponentenübergreifende Styling unterstützt werden.

Also einfach machen:

:host >>> .child {}

In parentder Stylesheet-Datei wurde das Problem behoben. Bitte beachten Sie, dass diese Lösung, wie im obigen Zitat angegeben, nur zwischenzeitlich erfolgt, bis ein erweitertes komponentenübergreifendes Styling unterstützt wird.

Chrillewoodz
quelle
Sieht so aus, als würden sie die Unterstützung für :: ng-deep angle.io/guide/component-styles#deprecated-deep--and-ng-deep
Jed Richards am
39

Sie sollten NICHT verwenden ::ng-deep, es ist veraltet. In Angular können Sie den Stil der Kinderkomponente vom übergeordneten Element aus ordnungsgemäß ändern encapsulation(lesen Sie die folgende Warnung, um die Auswirkungen zu verstehen):

import { ViewEncapsulation } from '@angular/core';

@Component({
    ....
    encapsulation: ViewEncapsulation.None
})

Und dann können Sie das CSS-Formular Ihrer Komponente ändern, ohne dass :: ng-deep erforderlich ist

.mat-sort-header-container {
  display:flex;
  justify-content:center;
}

WARNUNG: Wenn Sie dies tun, werden alle CSS-Regeln, die Sie für diese Komponente schreiben, global.

Um den Umfang Ihres CSS nur auf diese Komponente zu beschränken, fügen Sie dem obersten Tag Ihrer Komponente eine CSS-Klasse hinzu und fügen Sie Ihr CSS "in" dieses Tag ein:

template:
    <div class='my-component'>
      <child-component class="first">First</child>
    </div>,

Scss-Datei:

.my-component {
  // All your css goes in there in order not to be global
}
Tonio
quelle
3
Dies ist die beste Antwort IMO, da es tatsächlich eine praktikable Alternative zu den bald veralteten ist ::ng-deep. Im Allgemeinen haben Komponenten ohnehin einen eigenen Selektor ( <my-component>, <div my-component>usw.), sodass nicht einmal ein Wrapper-Element mit einer speziellen Klasse erforderlich ist.
Alex Walker
@AlexWalker Dies ist möglicherweise die beste Antwort für Ihre Situation, aber es ist erwähnenswert, dass sie nur die Hälfte der Frage des OP beantwortet: Diese Methode ermöglicht es CSS, sich wie gewohnt von oben nach unten zu verbreiten, aber aufgrund des Wegwerfens ALLER Kapselung nicht Beschränken Sie dieses Styling nicht auf Kinder eines bestimmten Elternteils . Wenn Sie die Kinder von parent1 in eine Richtung und die Kinder von parent2 in eine andere Richtung stylen, kämpfen diese CSS-Regeln jetzt an beiden Stellen gegeneinander. Das kann nervenaufreibend schmerzhaft sein (und Angular hat die Kapselung hinzugefügt, um dies zu vermeiden).
Ruffin
@ruffin Genau aus diesem Grund habe ich die Warnung in meine Antwort eingefügt, um die Auswirkungen dieser Technik zu verstehen und um zu verstehen, wie Sie mithilfe eines Top-CSS-Tags auf Ihrer Komponente "manuell kapseln" können
Tonio,
1
@Tonio - Ja, stimmte zu; antwortete eher direkt auf Alex als auf dich. Sein Kommentar " Es besteht also nicht einmal die Notwendigkeit eines Wrapper-Elements mit einer speziellen Klasse " machte mir ein wenig Angst. Vielleicht für eine bestimmte Situation, aber es gibt einen Grund, warum Angular Zeit für die Unterstützung der Kapselung "verschwendet". Diese Antwort ist in bestimmten Fällen eine praktikable Lösung, aber, wie Sie sagen, im Allgemeinen eine potenziell gefährliche. Die Lösung von MatthewB formatiert beispielsweise Kinder unter Beibehaltung der Kapselung (aber es wird sehr chaotisch, wenn Sie mehr als eine Generation von untergeordneten Komponenten haben).
Ruffin
19

Leider scheint der / deep / Selektor (zumindest in Chrome) veraltet zu sein. Https://www.chromestatus.com/features/6750456638341120

Kurz gesagt, es scheint (derzeit) keine andere langfristige Lösung zu geben, als Ihre untergeordnete Komponente dazu zu bringen, Dinge dynamisch zu gestalten.

Sie können Ihrem Kind ein Stilobjekt übergeben und es anwenden lassen über:
<div [attr.style]="styleobject">

Oder wenn Sie einen bestimmten Stil haben, können Sie Folgendes verwenden:
<div [style.background-color]="colorvar">

Weitere Diskussionen dazu: https://github.com/angular/angular/issues/6511

Matthew B.
quelle
16

Hatte das gleiche Problem. Wenn Sie also angle2-cli mit scss / sass verwenden und '/ deep /' anstelle von '>>>' verwenden, wird der letzte Selektor noch nicht unterstützt (funktioniert aber hervorragend mit CSS).

SergiySev
quelle
11

Wenn Sie gezielter auf die eigentliche untergeordnete Komponente ausgerichtet sein möchten, sollten Sie die folgenden Schritte ausführen. Auf diese Weise sind andere untergeordnete Komponenten, die denselben Klassennamen haben, nicht betroffen.

Plunker: https://plnkr.co/edit/ooBRp3ROk6fbWPuToytO?p=preview

Beispielsweise:

import {Component, NgModule } from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>I'm the host parent</h2>
      <child-component class="target1"></child-component><br/>
      <child-component class="target2"></child-component><br/>
      <child-component class="target3"></child-component><br/>
      <child-component class="target4"></child-component><br/>
      <child-component></child-component><br/>
    </div>
  `,
  styles: [`

  /deep/ child-component.target1 .child-box {
      color: red !important; 
      border: 10px solid red !important;
  }  

  /deep/ child-component.target2 .child-box {
      color: purple !important; 
      border: 10px solid purple !important;
  }  

  /deep/ child-component.target3 .child-box {
      color: orange !important; 
      border: 10px solid orange !important;
  }  

  /* this won't work because the target component is spelled incorrectly */
  /deep/ xxxxchild-component.target4 .child-box {
      color: orange !important; 
      border: 10px solid orange !important;
  }  

  /* this will affect any component that has a class name called .child-box */
  /deep/ .child-box {
      color: blue !important; 
      border: 10px solid blue !important;
  }  


  `]
})
export class App {
}

@Component({
  selector: 'child-component',
  template: `
    <div class="child-box">
      Child: This is some text in a box
    </div>
  `,
  styles: [`
    .child-box {
      color: green;    
      border: 1px solid green;
    }
  `]
})
export class ChildComponent {
}


@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, ChildComponent ],
  bootstrap: [ App ]
})
export class AppModule {}

Hoffe das hilft!

Codematrix

Code5
quelle
9

Eigentlich gibt es noch eine Option. Welches ist ziemlich sicher. Sie können ViewEncapsulation.None verwenden, ABER alle Ihre Komponentenstile in das Tag (auch bekannt als Selector) einfügen. Aber trotzdem bevorzugen Sie immer einen globalen Stil plus gekapselte Stile.

Hier ist modifiziertes Denis Rybalka Beispiel:

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'parent',
  styles: [`
    parent {
      .first {
        color:blue;
      }
      .second {
        color:red;
      }
    }
 `],
 template: `
    <div>
      <child class="first">First</child>
      <child class="second">Second</child>
    </div>`,
  encapsulation: ViewEncapsulation.None,
})
export class ParentComponent  {
  constructor() { }
}
ilius33
quelle
7

In Angular gibt es einige Optionen, um dies zu erreichen:

1) Sie können Deep-CSS-Selektoren verwenden

:host >>> .childrens {
     color: red;
 }

2) Sie können auch die Ansichtskapselung ändern, die standardmäßig auf Emuliert eingestellt ist. Sie kann jedoch problemlos in Native geändert werden, wobei die native Browser-Implementierung von Shadow DOM verwendet wird. In Ihrem Fall müssen Sie sie nur deaktivieren

Zum Beispiel: `

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'parent',
  styles: [`
    .first {
      color:blue;
    }
    .second {
      color:red;
    }
 `],
 template: `
    <div>
      <child class="first">First</child>
      <child class="second">Second</child>
    </div>`,
  encapsulation: ViewEncapsulation.None,
 })
 export class ParentComponent  {
   constructor() {

   }
 }
Denis Rybalka
quelle
3
Tatsächlich bedeutet dies, dass Stile den gesamten Dom betreffen, nicht nur untergeordnete Elemente.
Kasper Ziemianek
7

Sie sollten keine CSS-Regeln für untergeordnete Komponentenelemente in eine übergeordnete Komponente schreiben, da eine Angular-Komponente eine in sich geschlossene Entität ist, die explizit deklarieren sollte, was für die Außenwelt verfügbar ist. Wenn sich das untergeordnete Layout in Zukunft ändert, können Ihre Stile für die untergeordneten Komponentenelemente, die über die SCSS-Dateien anderer Komponenten verteilt sind, leicht beschädigt werden, wodurch Ihr Stil sehr fragil wird. Das ist, wasViewEncapsulation ist CSS gedacht. Andernfalls wäre es dasselbe, wenn Sie privaten Feldern einer Klasse aus einer anderen Klasse in der objektorientierten Programmierung Werte zuweisen könnten.

Daher sollten Sie eine Reihe von Klassen definieren, die Sie auf das untergeordnete Hostelement anwenden können, und implementieren, wie das untergeordnete Element darauf reagiert.

Technisch könnte dies wie folgt erfolgen:

// child.component.html:
<span class="label-1"></span>

// child.component.scss:
:host.child-color-black {
    .label-1 {
        color: black;
    }
}

:host.child-color-blue {
    .label-1 {
        color: blue ;
    }
}

// parent.component.html:
<child class="child-color-black"></child>
<child class="child-color-blue"></child>

Mit anderen Worten, Sie verwenden den :hostPseudo-Selektor, der von Angular + CSS-Klassen bereitgestellt wird, um mögliche untergeordnete Stile in der untergeordneten Komponente selbst zu definieren. Sie haben dann die Möglichkeit, diese Stile von außen auszulösen, indem Sie vordefinierte Klassen auf das <child>Hostelement anwenden .

Alexander Abakumov
quelle
Sieht nach einer guten Lösung aus. Gibt es eine Datei parent.component.scss? Wenn ja, möchten Sie es geben?
Manohar Reddy Poreddy
@ManoharReddyPoreddy Es sollte kein Styling in parent.component.scssBezug auf das Styling der untergeordneten Komponente geben. Dies ist der einzige Zweck dieses Ansatzes. Warum brauchen Sie parent.component.scss?
Alexander Abakumov
Ich bin mir nicht sicher, kenne nur ein bisschen CSS. Können Sie eine vollständige Lösung auf jsbin oder anderen teilen? Ihre Lösung kann eine zukünftige Lösung für alle sein.
Manohar Reddy Poreddy
2
@ManoharReddyPoreddy Ich würde Ihnen empfehlen, diese Codeteile zuerst in der Praxis auszuprobieren. Wenn Sie dann auf Probleme stoßen, haben Sie eine bestimmte Frage, die ich beantworten oder empfehlen kann, um ein bestimmtes Thema zu untersuchen und zu verstehen, wie Sie Ihr Problem beheben können. Ich erwähnte ViewEncapsulationnur, weil sein Standardwert zur OP-Frage führt. Sie müssen keinen anderen ViewEncapsulationCode zuweisen, damit der obige Code funktioniert.
Alexander Abakumov
1
+1 Danke. Wir werden in Zukunft wiederkommen, um diese Lösung zu nutzen, die sich heute für :: ng-deep stackoverflow.com/a/36528769/984471 entschieden hat.
Manohar Reddy Poreddy
5

Ich finde es viel sauberer, eine @ INPUT-Variable zu übergeben, wenn Sie Zugriff auf den untergeordneten Komponentencode haben:

Die Idee ist, dass der Elternteil dem Kind sagt, wie es aussehen soll, und das Kind entscheidet, wie der Zustand angezeigt werden soll. Es ist eine schöne Architektur

SCSS-Weg:

.active {
  ::ng-deep md-list-item {
    background-color: #eee;
  }
}

Besserer Weg: - selectedVariable verwenden:

<md-list>
    <a
            *ngFor="let convo of conversations"
            routerLink="/conversations/{{convo.id}}/messages"
            #rla="routerLinkActive"
            routerLinkActive="active">
        <app-conversation
                [selected]="rla.isActive"
                [convo]="convo"></app-conversation>
    </a>
</md-list>
Robert King
quelle
2
Auch schwer zu warten, insbesondere für rekursive Komponenten.
Erik Philips
2

Ab heute (Angular 9) verwendet Angular ein Shadow-DOM , um die Komponenten als benutzerdefinierte HTML-Elemente anzuzeigen . Eine elegante Möglichkeit, diese benutzerdefinierten Elemente zu formatieren, ist möglicherweise die Verwendung benutzerdefinierter CSS-Variablen . Hier ist ein allgemeines Beispiel:

class ChildElement extends HTMLElement {
  constructor() {
    super();
    
    var shadow = this.attachShadow({mode: 'open'});
    var wrapper = document.createElement('div');
    wrapper.setAttribute('class', 'wrapper');
    
    // Create some CSS to apply to the shadow dom
    var style = document.createElement('style');
    
    style.textContent = `
    
      /* Here we define the default value for the variable --background-clr */
      :host {
        --background-clr: green;
      }
      
      .wrapper {
        width: 100px;
        height: 100px;
        background-color: var(--background-clr);
        border: 1px solid red;
      }
    `;
    
    shadow.appendChild(style);
    shadow.appendChild(wrapper);
  }
}

// Define the new element
customElements.define('child-element', ChildElement);
/* CSS CODE */

/* This element is referred as :host from the point of view of the custom element. Commenting out this CSS will result in the background to be green, as defined in the custom element */

child-element {
  --background-clr: yellow; 
}
<div>
  <child-element></child-element>
</div>

Wie aus dem obigen Code hervorgeht, erstellen wir ein benutzerdefiniertes Element, wie es Angular für jede Komponente tun würde, und überschreiben dann die für die Hintergrundfarbe verantwortliche Variable innerhalb der Schattenwurzel des benutzerdefinierten Elements aus dem globalen Bereich .

In einer Angular-App könnte dies etwa so aussehen:

parent.component.scss

child-element {
  --background-clr: yellow;
}

child-element.component.scss

:host {
  --background-clr: green;
}

.wrapper {
  width: 100px;
  height: 100px;
  background-color: var(--background-clr);
  border: 1px solid red;
}
vivanov
quelle
0

Die schnelle Antwort lautet: Sie sollten dies überhaupt nicht tun. Es unterbricht die Kapselung von Komponenten und untergräbt den Nutzen von in sich geschlossenen Komponenten. Wenn Sie ein Prop-Flag an die untergeordnete Komponente übergeben möchten, kann diese selbst entscheiden, wie sie anders rendern oder bei Bedarf anderes CSS anwenden soll.

<parent>
  <child [foo]="bar"></child>
</parent>

Angular lehnt alle Möglichkeiten ab, die Kinderstile der Eltern zu beeinflussen.

https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep

Jed Richards
quelle
Nun, sie haben in ihren Dokumenten ausdrücklich gesagt, dass sie es irgendwann tun, was ich denke, dass sie es tun werden. Ich bin jedoch damit einverstanden, dass dies nicht so bald geschieht.
Jed Richards
Sie werden also ihre eigene Materialbibliothek so gut wie unbrauchbar machen. Ich konnte in keiner Bibliothek ein Standardthema verwenden, da jeder Kunde sein eigenes Design benötigt. Normalerweise möchten Sie nur die Funktionalität einer Komponente. Ich kann nicht sagen, dass ich ihre allgemeine Logik hinter dieser Entscheidung verstehe.
Chrillewoodz
0

Ich hatte auch dieses Problem und wollte keine veraltete Lösung verwenden, also endete ich mit:

in parrent

 <dynamic-table
  ContainerCustomStyle='width: 400px;'
  >
 </dynamic-Table>

untergeordnete Komponente

@Input() ContainerCustomStyle: string;

im Kind in HTML div

 <div class="container mat-elevation-z8"
 [style]='GetStyle(ContainerCustomStyle)' >

und im Code

constructor(private sanitizer: DomSanitizer) {  }

  GetStyle(c) {
    if (isNullOrUndefined(c)) { return null; }
    return  this.sanitizer.bypassSecurityTrustStyle(c);
  }

funktioniert wie erwartet und sollte nicht veraltet sein;)

d00lar
quelle
Interessant! Am Ende hatte ich (vorerst) etwas Ähnliches. Woher bekommen Sie DomSanitizer? Bearbeiten: Gefunden: angle.io/api/platform-browser/DomSanitizer
Zaphoid
Ja, in Version 7 ist es nativ. Sie müssen nur die Injektion im Konstruktor anfordern. ;), in älteren habe ich keine Ahnung, ob es existiert - ich habe von v7 angefangen;)
d00lar
0

Als das Internet aktualisiert wurde, bin ich auf eine Lösung gestoßen.

Zuerst einige Vorbehalte.

  1. Tu es immer noch nicht. Zur Verdeutlichung würde ich keine untergeordneten Komponenten planen, mit denen Sie sie formatieren können. SOC. Wenn Sie als Komponentendesigner dies zulassen möchten, haben Sie umso mehr Leistung.
  2. Wenn Ihr Kind nicht im Schatten lebt, funktioniert dies bei Ihnen nicht.
  3. Wenn Sie einen Browser unterstützen müssen, der keinen Schattendom haben kann, funktioniert dies auch nicht für Sie.

Markieren Sie zunächst die Kapselung Ihrer untergeordneten Komponente als Schatten, damit sie im tatsächlichen Schattendom gerendert wird. Fügen Sie zweitens das Teilattribut zu dem Element hinzu, das das übergeordnete Element formatieren soll. Im Komponenten-Stylesheet Ihrer Eltern können Sie mit der Methode :: part () darauf zugreifen

Leuchtend
quelle
-1

Ich schlage ein Beispiel vor, um es klarer zu machen, da angular.io/guide/component-styles Folgendes angibt:

Der Schatten-durchdringende Nachkommen-Kombinator ist veraltet und die Unterstützung wird von den wichtigsten Browsern und Tools entfernt. Aus diesem Grund planen wir, die Unterstützung in Angular einzustellen (für alle 3 von / deep /, >>> und :: ng-deep). Bis dahin sollte :: ng-deep für eine breitere Kompatibilität mit den Tools bevorzugt werden.

Auf app.component.scss, importieren Sie Ihre , *.scsswenn nötig. _colors.scsshat einige gemeinsame Farbwerte:

$button_ripple_red: #A41E34;
$button_ripple_white_text: #FFF;

Wenden Sie eine Regel auf alle Komponenten an

Alle Schaltflächen mit btn-redKlasse werden gestylt.

@import `./theme/sass/_colors`;

// red background and white text
:host /deep/ button.red-btn {
    color: $button_ripple_white_text;
    background: $button_ripple_red;
}

Wenden Sie eine Regel auf eine einzelne Komponente an

Alle Schaltflächen mit btn-redKlasse für app-loginKomponente werden so gestaltet.

@import `./theme/sass/_colors`;

/deep/ app-login button.red-btn {
    color: $button_ripple_white_text;
    background: $button_ripple_red;
}
AndreaM16
quelle
-1

Ich habe es außerhalb von Angular gelöst. Ich habe ein freigegebenes scss definiert, das ich in meine Kinder importiere.

shared.scss

%cell {
  color: #333333;
  background: #eee;
  font-size: 13px;
  font-weight: 600;
}

child.scss

@import 'styles.scss';
.cell {
  @extend %cell;
}

Mein vorgeschlagener Ansatz ist ein Weg, um das Problem zu lösen, nach dem das OP gefragt hat. Wie bereits mehrfach erwähnt, wird :: ng-deep ,: ng-host abgeschrieben, und das Deaktivieren der Kapselung ist meiner Ansicht nach ein zu großer Codeverlust.

Jakub
quelle