J'ai un composant parent:
<parent></parent>
Et je veux remplir ce groupe avec des composants enfants:
<parent>
<child></child>
<child></child>
<child></child>
</parent>
Modèle parent:
<div class="parent">
<!-- Children goes here -->
<ng-content></ng-content>
</div>
Modèle enfant:
<div class="child">Test</div>
Étant donné que parent
et child
sont deux composants distincts, leurs styles sont verrouillés dans leur propre domaine.
Dans mon composant parent, j'ai essayé de faire:
.parent .child {
// Styles for child
}
Mais les styles .child
ne sont pas appliqués aux composants child
.
J'ai essayé d'utiliser styleUrls
pour inclure la feuille de style de parent
dans le composant child
afin de résoudre le problème de portée:
// child.component.ts
styleUrls: [
'./parent.component.css',
'./child.component.css',
]
Mais cela n'a pas aidé, a également essayé dans l'autre sens en récupérant la feuille de style child
dans parent
mais cela n'a pas aidé non plus.
Alors, comment qualifiez-vous les composants enfants inclus dans un composant parent?
Ne le fais pas, si tu peux l'éviter. Comme Devon Sans le fait remarquer dans les commentaires: Cette fonctionnalité sera probablement obsolète.
À partir de Angular 4.3.0, tous les combinartors css de piercing étaient obsolètes. L’équipe angulaire a présenté un nouveau combinateur ::ng-deep
(il s’agit toujours d’un niveau expérimental et non de la manière complète et finale) comme indiqué ci-dessous,
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>
`
Vous pouvez utiliser encapsulation mode
et/ou piercing CSS combinators >>>, /deep/ and ::shadow
exemple de travail: 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>
`
UPDATE 3:
::ng-deep
est également obsolète, ce qui signifie que vous ne devriez plus faire cela du tout. Il n'est pas clair en quoi cela affecte les éléments pour lesquels vous devez remplacer les styles des composants enfants d'un composant parent. Pour moi, il semble étrange que cela soit supprimé complètement, car cela affecterait les choses en tant que bibliothèques où vous devez remplacer les styles dans un composant de bibliothèque.
Commentez si vous avez un aperçu de cela.
UPDATE 2:
Depuis /deep/
et tous les autres sélecteurs de perforation d'ombre sont maintenant obsolètes. Angular drop ::ng-deep
qui devrait être utilisé à la place pour une compatibilité plus large.
METTRE À JOUR:
Si vous utilisez Angular-CLI, vous devez utiliser /deep/
au lieu de >>>
, sinon cela ne fonctionnera pas.
ORIGINAL:
Après être allé sur la page Github de Angular2 et avoir fait une recherche aléatoire pour "style", j'ai trouvé cette question: Angular 2 - innerHTML styling
Ce qui dit d'utiliser quelque chose qui a été ajouté dans 2.0.0-beta.10
, les sélecteurs >>>
et ::shadow
.
(>>>) (et les équivalents/deep /) et :: shadow ont été ajoutés dans 2.0.0-beta.10. Ils sont similaires aux combinateurs CSS fantômes DOM (qui sont obsolètes) et ne fonctionnent qu'avec l’encapsulation: ViewEncapsulation.Emulated, qui est la valeur par défaut dans Angular2. Ils fonctionnent probablement aussi avec ViewEncapsulation.None mais ne sont alors ignorés que parce qu'ils ne sont pas nécessaires. Ces combinateurs ne sont qu'une solution intermédiaire jusqu'à ce que des fonctionnalités plus avancées pour le style multi-composants soient prises en charge.
Alors simplement faire:
:Host >>> .child {}
Dans la feuille de style de parent
, le problème a été résolu. Veuillez noter que, comme indiqué dans la citation ci-dessus, cette solution n'est intermédiaire que jusqu'à ce que le style multi-composants avancé soit pris en charge.
Même problème, donc si vous utilisez angular2-cli avec scss/sass, utilisez '/ deep /' au lieu de '>>>', le dernier sélecteur n'est pas encore pris en charge (mais fonctionne parfaitement avec css).
Malheureusement, il semble que le sélecteur/deep/soit obsolète (du moins sous Chrome) https://www.chromestatus.com/features/6750456638341120
En résumé, il semble qu’il n’existe (actuellement) pas de solution à long terme autre que d’obliger votre composant enfant à styliser les éléments de manière dynamique .
Vous pouvez passer un objet de style à votre enfant et le faire appliquer via:<div [attr.style]="styleobject">
Ou si vous avez un style spécifique, vous pouvez utiliser quelque chose comme:<div [style.background-color]="colorvar">
Plus de discussion à ce sujet: https://github.com/angular/angular/issues/6511
Si vous souhaitez cibler davantage le composant enfant, procédez comme suit. Ainsi, si d'autres composants enfants partagent le même nom de classe, ils ne seront pas affectés.
Plunker: https://plnkr.co/edit/ooBRp3ROk6fbWPuToytO?p=preview
Par exemple:
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 {}
J'espère que cela t'aides!
codematrix
Si vous ne voulez pas utiliser :: ng-deep, vous pouvez le faire, ce qui semble être la bonne manière:
import { ViewEncapsulation } from '@angular/core';
@Component({
....
encapsulation: ViewEncapsulation.None
})
Et ensuite, vous pourrez modifier la forme css de votre composant sans avoir besoin de :: ng-deep
.mat-sort-header-container {
display:flex;
justify-content:center;
}
ATTENTION: faites attention car si votre composant a beaucoup d'enfants, le css que vous écrivez pour ce composant peut affecter tous les enfants!
Angular offre quelques options pour y parvenir:
1) Vous pouvez utiliser des sélecteurs deep css
:Host >>> .childrens {
color: red;
}
2) Vous pouvez également modifier l’encapsulation de la vue, elle est définie par défaut sur Emulé, mais peut également être remplacée par Native qui utilise la mise en œuvre du navigateur Shadow DOM, vous devez simplement le désactiver
Par exemple: `
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() {
}
}
Je trouve beaucoup plus propre de passer une variable @INPUT si vous avez accès au code du composant enfant:
L'idée est que le parent indique à l'enfant quel doit être son état d'apparence et que l'enfant décide comment afficher l'état. C'est une belle architecture
SCSS Way:
.active {
::ng-deep md-list-item {
background-color: #eee;
}
}
Meilleure façon: - utilisez la variable selected
:
<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>
Vous ne devez pas écrire de règles CSS pour un élément de composant enfant dans un composant parent, car un composant angulaire est une entité autonome qui devrait déclarer explicitement ce qui est disponible pour le monde extérieur. Si la disposition des enfants change à l'avenir, les styles de ces éléments de composants enfants disséminés dans les fichiers SCSS des autres composants pourraient facilement se briser, ce qui rendrait votre style très fragile. C'est ce que ViewEncapsulation
est dans le cas de CSS. Sinon, il en irait de même si vous pouviez affecter des valeurs à des champs privés d'une classe à partir d'une autre classe dans la programmation orientée objet.
Par conséquent, vous devez définir un ensemble de classes que vous pouvez appliquer à l'élément hôte enfant et mettre en œuvre la manière dont l'enfant y répond.
Techniquement, cela pourrait être fait comme suit:
// 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>
En d'autres termes, vous utilisez le pseudo-sélecteur :Host
fourni par Angular + et l'ensemble de classes CSS pour définir les styles enfant possibles dans le composant enfant même. Vous avez ensuite la possibilité de déclencher ces styles de l'extérieur en appliquant des classes prédéfinies à l'élément hôte <child>
.
j'ai également eu ce problème et je ne voulais pas utiliser une solution obsolète donc je me suis retrouvé avec:
en parrent
<dynamic-table
ContainerCustomStyle='width: 400px;'
>
</dynamic-Table>
composant enfant
@Input() ContainerCustomStyle: string;
chez l'enfant en html div
<div class="container mat-elevation-z8"
[style]='GetStyle(ContainerCustomStyle)' >
et en code
constructor(private sanitizer: DomSanitizer) { }
GetStyle(c) {
if (isNullOrUndefined(c)) { return null; }
return this.sanitizer.bypassSecurityTrustStyle(c);
}
fonctionne comme prévu et ne devrait pas être déconseillé;)
La réponse rapide est que vous ne devriez pas faire cela du tout. Il casse l’encapsulation de composants et compromet l’avantage que vous retirez des composants autonomes. Envisagez de passer un indicateur prop au composant enfant. Celui-ci peut alors décider lui-même comment rendre le rendu différemment ou appliquer un code CSS différent, si nécessaire.
<parent>
<child [foo]="bar"></child>
</parent>
Angular décourage tous les moyens d’affecter les styles d’enfant aux parents.
https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep
En fait, il y a encore une option. Ce qui est plutôt sûr. Vous pouvez utiliser ViewEncapsulation.None BUT mais placez tous vos styles de composant dans sa balise (sélecteur) Quoi qu'il en soit, préférez toujours un style global plus des styles encapsulés.
Voici l'exemple modifié de Denis Rybalka:
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() { }
}
Je propose un exemple pour le rendre plus clair, car angular.io/guide/component-styles déclare:
Le combinateur de descendants perçant les ombres est déconseillé et la prise en charge est supprimée des principaux navigateurs et outils. En tant que tel, nous prévoyons de supprimer le support angulaire (pour les 3 utilisateurs de/deep /, >>> et :: ng-deep). Jusque-là: ng-deep devrait être préféré pour une compatibilité plus large avec les outils.
Sur app.component.scss
, importez votre *.scss
si nécessaire. _colors.scss
a des valeurs de couleur communes:
$button_ripple_red: #A41E34;
$button_ripple_white_text: #FFF;
Appliquer une règle à tous les composants
Tous les boutons ayant la classe btn-red
seront stylés.
@import `./theme/sass/_colors`;
// red background and white text
:Host /deep/ button.red-btn {
color: $button_ripple_white_text;
background: $button_ripple_red;
}
Appliquer une règle à un seul composant
Tous les boutons ayant la classe btn-red
sur le composant app-login
seront stylés.
@import `./theme/sass/_colors`;
/deep/ app-login button.red-btn {
color: $button_ripple_white_text;
background: $button_ripple_red;
}