Jak stylizować komponenty potomne z pliku CSS komponentu macierzystego?

264

Mam element nadrzędny:

<parent></parent>

I chcę zapełnić tę grupę komponentami potomnymi:

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

Szablon nadrzędny:

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

Szablon podrzędny:

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

Ponieważ parenti childsą to dwa osobne komponenty, ich style są zablokowane we własnym zakresie.

W moim komponencie nadrzędnym próbowałem:

.parent .child {
  // Styles for child
}

Ale .childstyle nie są stosowane do childkomponentów.

Próbowałem styleUrlsdołączyć parentarkusz stylów do childkomponentu, aby rozwiązać problem z zakresem:

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

Ale to nie pomogło, próbowałem też w inny sposób, pobierając childarkusz stylów do, parentale to też nie pomogło.

Jak więc stylizować komponenty potomne zawarte w komponencie macierzystym?

Chrillewoodz
źródło
1
Zobacz także stackoverflow.com/questions/34542143/…
Günter Zöchbauer,
Zobacz moją odpowiedź całkowicie przyjazną dla paradygmatów .
Alexander Abakumov

Odpowiedzi:

242

Aktualizacja - najnowszy sposób

Nie rób tego, jeśli możesz tego uniknąć. Jak zauważa Devon Sans w komentarzach: Ta funkcja najprawdopodobniej będzie przestarzała.

Aktualizacja - nowsza droga

Od Angulara 4.3.0 wszystkie przebijające kombinatory css były przestarzałe. Zespół Angular wprowadził nowy kombinator ::ng-deep (wciąż jest na poziomie eksperymentalnym, a nie na pełnej i końcowej drodze), jak pokazano poniżej,

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>      
    `


Stara droga

Możesz użyć encapsulation modei / lubpiercing CSS combinators >>>, /deep/ and ::shadow

przykład roboczy: 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>      
`
mikroniki
źródło
3
Przebijające kombinatory CSS są jednak przestarzałe w Chrome
Robin-Hoodie
22
Zespół Angular planuje również zrezygnować z obsługi :: ng-deep. Z ich dokumentów: „Kombinator przebijający cień potomka jest przestarzały, a wsparcie jest usuwane z głównych przeglądarek i narzędzi. W związku z tym planujemy porzucić wsparcie w Angular (dla wszystkich 3 z / deep /, >>> i :: ng- deep). Do tego czasu należy preferować :: ng-deep, aby uzyskać szerszą kompatybilność z narzędziami. ” angular.io/guide/component-styles#deprecated-deep--and-ng-deep .
Devon Sams,
5
Dopóki pozostaje to zaakceptowaną odpowiedzią, ludzie będą wprowadzani w błąd. :: ng-deep nie powinno być używane jako punkty @DevonSams w powyższym komentarzu.
Kostas Siabanis
1
::ng-deepjest teraz przestarzałe , nie polecam go używać w przyszłych aplikacjach
Wilt
11
Wycofanie czegoś bez podania alternatywy nie jest prawdopodobnie najlepszym rozwiązaniem.
tehlivi
56

AKTUALIZACJA 3:

::ng-deepjest również przestarzałe, co oznacza, że ​​nie powinieneś już tego robić. Nie jest jasne, w jaki sposób wpływa to na rzeczy, w których należy zastąpić style w komponentach podrzędnych z komponentu nadrzędnego. Wydaje mi się dziwne, jeśli zostanie to całkowicie usunięte, ponieważ jak wpłynęłoby to na biblioteki, w których należy przesłonić style w komponencie biblioteki?

Skomentuj, jeśli masz wgląd w to.

AKTUALIZACJA 2:

Ponieważ /deep/wszystkie pozostałe selektory przebijające cień są teraz przestarzałe. Spadek kątowy, ::ng-deepktóry należy zastosować zamiast tego dla większej kompatybilności.

AKTUALIZACJA:

Jeśli używasz Angular-CLI, musisz użyć /deep/zamiast tego, >>>bo inaczej nie będzie działać.

ORYGINALNY:

Po przejściu na stronę Github w Angular2 i przeprowadzeniu losowego wyszukiwania „stylu” znalazłem to pytanie: Angular 2 - stylizacja innerHTML

Który powiedział, aby użyć czegoś, co zostało dodane 2.0.0-beta.10, selektorów >>>i ::shadow.

(>>>) (i odpowiednik / deep /) i :: shadow zostały dodane w wersji 2.0.0-beta.10. Są one podobne do cienia DOM CSS (które są przestarzałe) i działają tylko z enkapsulacją: ViewEncapsulation.Emulated, która jest domyślna w Angular2. Prawdopodobnie działają również z ViewEncapsulation.None, ale są wtedy ignorowane, ponieważ nie są konieczne. Te kombinatory są jedynie rozwiązaniem pośrednim, dopóki nie są obsługiwane bardziej zaawansowane funkcje stylizacji między komponentami.

Po prostu robienie:

:host >>> .child {}

W parent„s pliku arkusza stylów rozwiązać ten problem. Należy pamiętać, jak stwierdzono w powyższym cytacie, to rozwiązanie jest tylko pośrednie, dopóki nie będzie obsługiwana bardziej zaawansowana stylizacja między komponentami.

Chrillewoodz
źródło
Wygląda na to, że zamierzają usunąć wsparcie dla :: ng-deep angular.io/guide/component-styles#deprecated-deep--and-ng-deep
Jed Richards
40

NIE powinieneś używać ::ng-deep, jest przestarzałe. W Angular właściwym sposobem zmiany stylu komponentu dziecięcego od rodzica jest użycie encapsulation(przeczytaj poniższe ostrzeżenie, aby zrozumieć konsekwencje):

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

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

I wtedy będziesz mógł modyfikować css ze swojego komponentu bez potrzeby :: :: -g-deep

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

OSTRZEŻENIE: Wykonanie tej czynności sprawi, że wszystkie reguły css, które napiszesz dla tego komponentu, będą globalne.

Aby ograniczyć zakres twojego css tylko do tego komponentu, dodaj klasę css do górnego tagu twojego komponentu i umieść css „wewnątrz” tego tagu:

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

Plik scss:

.my-component {
  // All your css goes in there in order not to be global
}
Tonio
źródło
3
To najlepsza odpowiedź IMO, ponieważ w rzeczywistości jest realną alternatywą dla przestarzałych ::ng-deep. Ogólnie rzecz biorąc, komponenty i tak mają swój własny selektor ( <my-component>, <div my-component>itp.), Więc nie ma nawet potrzeby stosowania elementu opakowania ze specjalną klasą.
Alex Walker
@AlexWalker To może być najlepsza odpowiedź na twoją sytuację, ale warto wspomnieć, że odpowiada tylko na połowę pytania OP: afaict: Ta metoda pozwala CSS na normalną propagację od góry do dołu, ale dzięki wyrzuceniu WSZYSTKIEGO hermetyzacji, nie robi nie ograniczaj tego stylu do dzieci określonego rodzica . Jeśli stylizujesz dzieci rodzica1 w jeden sposób, a dzieci rodzica2 w inny sposób, te reguły CSS będą teraz ze sobą walczyć w obu miejscach. To może być przytłaczająco bolesne (i Angular dodał enkapsulację, aby tego uniknąć).
ruffin
@ruffin Właśnie dlatego dodałem ostrzeżenie w mojej odpowiedzi, aby zrozumieć konsekwencje korzystania z tej techniki i jak „ręcznie enkapsulować” za pomocą górnego tagu css w twoim komponencie
Tonio,
1
@Tonio - Tak, uzgodniono; odpowiadał bezpośrednio na Alexa, a nie na ciebie. Jego komentarz „ więc nie ma nawet potrzeby stosowania elementu opakowania ze specjalną klasą ” trochę mnie przeraził. Może w konkretnej sytuacji, ale jest powód, dla którego Angular „marnuje” czas na kapsułkowanie. Ta odpowiedź jest praktycznym rozwiązaniem w określonych przypadkach, ale, jak mówisz, jest ogólnie potencjalnie niebezpieczna. Rozwiązanie MatthewB , np. Stylizuje dzieci, zachowując enkapsulację (ale robi się naprawdę bałagan, jeśli masz więcej niż jedną generację komponentów potomnych).
ruffin
19

Niestety wygląda na to, że selektor / deep / jest przestarzały (przynajmniej w Chrome) https://www.chromestatus.com/features/6750456638341120

Krótko mówiąc, wydaje się, że nie ma (obecnie) długoterminowego rozwiązania innego niż jakoś sprawić, by element podrzędny stylizował rzeczy dynamicznie.

Możesz przekazać dziecku obiekt stylu i zastosować go przez:
<div [attr.style]="styleobject">

Lub jeśli masz określony styl, możesz użyć czegoś takiego:
<div [style.background-color]="colorvar">

Więcej dyskusji na ten temat: https://github.com/angular/angular/issues/6511

Matthew B.
źródło
16

Miał ten sam problem, więc jeśli używasz angular2-cli ze scss / sass użyj '/ deep /' zamiast '>>>', ostatni selektor nie jest jeszcze obsługiwany (ale działa świetnie z css).

SergiySev
źródło
11

Jeśli chcesz być bardziej ukierunkowany na rzeczywisty komponent potomny, wykonaj następujące czynności. W ten sposób, jeśli inne komponenty potomne będą miały tę samą nazwę klasy, nie będzie to miało wpływu.

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

Na przykład:

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 {}

Mam nadzieję że to pomoże!

kodematrix

kod5
źródło
9

W rzeczywistości jest jeszcze jedna opcja. Co jest raczej bezpieczne. Możesz użyć ViewEncapsulation.Nie ALE wstawić wszystkie style komponentów do jego znacznika (czyli selektora). Ale i tak zawsze preferuję styl globalny plus style zamknięte.

Oto zmodyfikowany przykład Denisa Rybalki:

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
źródło
7

Istnieje kilka opcji osiągnięcia tego w Angular:

1) Możesz używać głębokich selektorów css

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

2) Możesz również zmienić enkapsulację widoku, która jest domyślnie ustawiona na Emulowane, ale można ją łatwo zmienić na Natywny, który korzysta z implementacji natywnej przeglądarki Shadow DOM, w twoim przypadku wystarczy go wyłączyć

Na przykład: `

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
źródło
3
W rzeczywistości oznacza to, że style wpływają na całą domenę, nie tylko na elementy potomne.
Kasper Ziemianek
7

Nie powinieneś pisać reguł CSS dla elementów podrzędnych w komponencie nadrzędnym, ponieważ komponent Angular jest samodzielną jednostką, która powinna jawnie deklarować, co jest dostępne dla świata zewnętrznego. Jeśli układ potomny zmieni się w przyszłości, twoje style dla tych elementów potomnych rozproszonych w plikach SCSS innych składników mogą łatwo ulec uszkodzeniu, przez co twoja stylizacja będzie bardzo delikatna. Po to ViewEncapsulationjest w przypadku CSS. W przeciwnym razie byłoby tak samo, gdybyś mógł przypisać wartości do pól prywatnych jakiejś klasy z dowolnej innej klasy w programowaniu obiektowym.

Dlatego należy zdefiniować zestaw klas, które można zastosować do podrzędnego elementu hosta i zaimplementować sposób, w jaki dziecko na nie reaguje.

Technicznie można to zrobić w następujący sposób:

// 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>

Innymi słowy, używasz :hostpseudoselektora dostarczonego przez Angular + zestaw klas CSS, aby zdefiniować możliwe style potomne w samym komponencie potomnym. Następnie możesz uruchomić te style z zewnątrz, stosując wstępnie zdefiniowane klasy do <child>elementu hosta.

Aleksander Abakumow
źródło
Wygląda na dobre rozwiązanie, czy istnieje plik parent.component.scss? jeśli tak, zechcesz to dać?
Manohar Reddy Poreddy,
@ManoharReddyPoreddy Nie powinno być stylizacji w parent.component.scsszwiązku ze stylizacją elementu potomnego. Jest to jedyny cel tego podejścia. Dlaczego musisz parent.component.scss?
Alexander Abakumov
Nie jestem pewien, po prostu poznaj trochę css. Czy możesz udostępnić pełne rozwiązanie na jsbin lub innym. Twoje rozwiązanie może być przyszłym rozwiązaniem dla każdego.
Manohar Reddy Poreddy,
2
@ManoharReddyPoreddy Proponuję najpierw wypróbować te fragmenty kodu w praktyce. Następnie, jeśli napotkasz jakieś problemy, będziesz mieć konkretne pytanie, na które mógłbym odpowiedzieć lub poradę, aby przyjrzeć się konkretnemu tematowi i uzyskać trochę zrozumienia, jak rozwiązać problem. Wspomniałem ViewEncapsulationtylko dlatego, że jego domyślna wartość prowadzi do pytania PO. Nie musisz przypisywać innego ViewEncapsulationkodu, aby powyższy kod działał.
Alexander Abakumov,
1
+1 Dziękuję. Wrócimy, aby wziąć to rozwiązanie w przyszłości, rozliczone na :: ng-deep stackoverflow.com/a/36528769/984471 na dziś.
Manohar Reddy Poreddy,
5

Uważam, że o wiele czystsze jest przekazywanie zmiennej @INPUT, jeśli masz dostęp do kodu komponentu potomnego:

Chodzi o to, że rodzic mówi dziecku, jaki powinien być jego wygląd, a dziecko decyduje, jak wyświetlić ten stan. To ładna architektura

Sposób SCSS:

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

Lepszy sposób: - użyj selectedzmiennej:

<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
źródło
2
Również trudne w utrzymaniu, szczególnie w przypadku komponentów rekurencyjnych.
Erik Philips
2

Na dzień dzisiejszy (Angular 9) Angular używa Shadow DOM do wyświetlania komponentów jako niestandardowych elementów HTML . Jednym ze eleganckich sposobów stylizowania tych niestandardowych elementów może być użycie niestandardowych zmiennych CSS . Oto ogólny przykład:

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>

Jak widać z powyższego kodu, tworzymy element niestandardowy, tak jak zrobiłby to Angular z każdym komponentem, a następnie zastępujemy zmienną odpowiedzialną za kolor tła w katalogu głównym cienia elementu niestandardowego, z zakresu globalnego .

W aplikacji Angular może to być coś takiego:

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
źródło
0

Szybka odpowiedź brzmi: w ogóle nie powinieneś tego robić. Łamie enkapsulację komponentów i podważa korzyści uzyskiwane z samodzielnych komponentów. Zastanów się nad przekazaniem flagi prop do komponentu potomnego, a następnie może sam zdecydować, jak renderować inaczej lub zastosować inny CSS, jeśli to konieczne.

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

Angular odrzuca wszelkie sposoby wpływania na styl dziecka przez rodziców.

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

Jed Richards
źródło
Cóż, powiedzieli wprost w swoich dokumentach, że w końcu to robią, co, jak sądzę, oznacza, że ​​to zrobią. Zgadzam się, ale nie nastąpi to w najbliższym czasie.
Jed Richards
Więc właściwie uczynią własną bibliotekę materiałów bezużyteczną. Nigdy nie byłem w stanie użyć domyślnego motywu w żadnej bibliotece, ponieważ każdy klient wymaga własnego projektu. Zwykle potrzebujesz tylko funkcji komponentu. Nie mogę powiedzieć, że rozumiem ich ogólną logikę stojącą za tą decyzją.
Chrillewoodz
0

Miałem również ten problem i nie chciałem używać przestarzałego rozwiązania, więc otrzymałem:

równolegle

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

składnik potomny

@Input() ContainerCustomStyle: string;

u dziecka w html div

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

i w kodzie

constructor(private sanitizer: DomSanitizer) {  }

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

działa zgodnie z oczekiwaniami i nie powinien być przestarzały;)

d00lar
źródło
Ciekawy! Skończyło się na czymś podobnym (na razie). Skąd bierzesz DomSanitizer? Edycja: Znaleziono: angular.io/api/platform-browser/DomSanitizer
Zaphoid
tak w v7 jest natywny, wystarczy poprosić o wstrzyknięcie go do konstruktora. ;), w starszych nie mam pojęcia, czy istniało - zacząłem od wersji 7;)
d00lar 24.04.19
0

W miarę aktualizacji Internetu natknąłem się na rozwiązanie.

Najpierw pewne zastrzeżenia.

  1. Nadal tego nie rób. Aby to wyjaśnić, nie planowałbym komponentów potomnych pozwalających na ich stylizację. SOC. Jeśli jako projektant komponentów chcesz na to pozwolić, tym więcej mocy dla Ciebie.
  2. Jeśli twoje dziecko nie mieszka w cienistym domu, to nie zadziała dla ciebie.
  3. Jeśli musisz obsługiwać przeglądarkę, która nie może mieć cienia, to również to nie zadziała.

Najpierw zaznacz enkapsulację komponentu podrzędnego jako cień, aby renderowała się w rzeczywistym cieniu. Po drugie, dodaj atrybut części do elementu, który chcesz nadać stylowi nadrzędnemu. W arkuszu stylów komponentów rodzica możesz użyć metody :: part (), aby uzyskać dostęp

Świetlny
źródło
-1

Proponuję przykład, aby to wyjaśnić, ponieważ angular.io/guide/component-styles stwierdza:

Kombinator przebijający cienie jest przestarzały, a wsparcie jest usuwane z głównych przeglądarek i narzędzi. W związku z tym planujemy porzucić wsparcie w Angular (dla wszystkich 3 / deep /, >>> i :: ng-deep). Do tego czasu należy preferować :: ng-deep, aby uzyskać szerszą kompatybilność z narzędziami.

Włącz app.component.scss, w *.scssrazie potrzeby zaimportuj . _colors.scssma kilka wspólnych wartości kolorów:

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

Zastosuj regułę do wszystkich komponentów

Wszystkie przyciski mające btn-redklasę będą stylizowane.

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

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

Zastosuj regułę do pojedynczego komponentu

Wszystkie przyciski mające btn-redklasę na app-loginkomponencie będą stylizowane.

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

/deep/ app-login button.red-btn {
    color: $button_ripple_white_text;
    background: $button_ripple_red;
}
AndreaM16
źródło
-1

Rozwiązałem to poza Angularem. Zdefiniowałem wspólny scss, który importuję do moich dzieci.

shared.scss

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

child.scss

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

Moje zaproponowane podejście jest sposobem rozwiązania problemu, o który pytał PO. Jak wspomniano przy wielu okazjach, :: ng-deep,: ng-host ulegnie deprecjacji, a wyłączenie enkapsulacji to po prostu zbyt duży wyciek kodu, moim zdaniem.

Kuba
źródło