¿Cómo se diseñan los componentes secundarios del archivo css del componente principal?

Tengo un componente principal:

 

Y quiero llenar este grupo con componentes secundarios:

      

Plantilla principal:

 

Plantilla de niño:

 
Test

Como parent e child son dos componentes separados, sus estilos están bloqueados en su propio ámbito.

En mi componente principal intenté hacer:

 .parent .child { // Styles for child } 

Pero los estilos .child no se están aplicando a los componentes child .

Intenté usar styleUrls para incluir la hoja de estilo del parent en child componente child para resolver el problema del scope:

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

Pero eso no sirvió, también intenté a la inversa al traer la hoja de estilo del child a la parent pero eso tampoco ayudó.

Entonces, ¿cómo se diseñan los componentes secundarios que se incluyen en un componente principal?

Actualización – Nueva forma

No lo hagas, si puedes evitarlo. Como señala Devon Sans en los comentarios: Probablemente esta característica se desaprovechará.

Actualización – Nueva forma

Desde Angular 4.3.0 , todos los combinadores css piercing fueron obsoletos. El equipo Angular presentó un nuevo combinador ::ng-deep (aún está a nivel experimental y no de manera completa y final) como se muestra a continuación,

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  //blue  //orange  //yellow  //pink  ` 

Vieja forma

Puede usar el encapsulation mode y / o los piercing CSS combinators >>>, /deep/ and ::shadow

ejemplo de trabajo: 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  //blue  //orange  //yellow  //pink  ` 

ACTUALIZACIÓN 3:

::ng-deep también está en desuso, lo que significa que ya no deberías hacer esto. No está claro cómo esto afecta las cosas donde necesita anular los estilos en los componentes secundarios de un componente principal. Para mí, parece extraño si esto se elimina por completo porque, ¿cómo afectaría esto a las cosas como bibliotecas en las que es necesario anular los estilos en un componente de la biblioteca?

Comente si tiene alguna idea al respecto.

ACTUALIZACIÓN 2:

Dado que /deep/ y todos los otros selectores de perforación de sombra ahora están en desuso. Angular drop ::ng-deep que debería usarse en su lugar para una compatibilidad más amplia.

ACTUALIZAR:

Si usa Angular-CLI, necesita usar /deep/ lugar de >>> o de lo contrario no funcionará.

ORIGINAL:

Después de ir a la página de Github de Angular2 y hacer una búsqueda aleatoria de “estilo” encontré esta pregunta: Angular 2: estilo HTML interno

Lo cual dice que use algo que se agregó en 2.0.0-beta.10 , los selectores >>> y ::shadow .

(>>>) (y el equivalente / profundo /) y :: sombra se agregaron en 2.0.0-beta.10. Son similares a los combinadores sombreados DOM CSS (que están en desuso) y solo funcionan con la encapsulación: ViewEncapsulation.Emulated que es el valor predeterminado en Angular2. Probablemente también trabajen con ViewEncapsulation.None, pero luego solo se ignoran porque no son necesarios. Estos combinadores son solo una solución intermedia hasta que se admitan características más avanzadas para el diseño de componentes cruzados.

Así que simplemente haciendo:

 :host >>> .child {} 

En el archivo de la hoja de estilo del parent resolvió el problema. Tenga en cuenta que, como se indica en la cita anterior, esta solución solo es intermedia hasta que se admite un estilo más avanzado de componentes cruzados.

Tenía el mismo problema, así que si está usando angular2-cli con scss / sass use ‘/ deep /’ en lugar de ‘>>>’, el último selector aún no es compatible (pero funciona muy bien con css).

Lamentablemente, parece que / deep / selector está en desuso (al menos en Chrome) https://www.chromestatus.com/features/6750456638341120

En resumen, parece que (en la actualidad) no existe una solución a largo plazo que no sea lograr de algún modo que el componente de su hijo dé un estilo dynamic.

Podría pasarle un objeto de estilo a su hijo y aplicarlo a través de:

O si tiene un estilo específico, puede usar algo como:

Más discusión relacionada con esto: https://github.com/angular/angular/issues/6511

Si desea estar más orientado al componente hijo real de lo que debería hacer, siga. De esta forma, si otros componentes secundarios comparten el mismo nombre de clase, no se verán afectados.

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

Por ejemplo:

 import {Component, NgModule } from '@angular/core' import {BrowserModule} from '@angular/platform-browser' @Component({ selector: 'my-app', template: ` 

I'm the host parent






`, 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: `
Child: This is some text in a box
`, styles: [` .child-box { color: green; border: 1px solid green; } `] }) export class ChildComponent { } @NgModule({ imports: [ BrowserModule ], declarations: [ App, ChildComponent ], bootstrap: [ App ] }) export class AppModule {}

¡Espero que esto ayude!

codematrix

Hay algunas opciones para lograr esto en Angular:

1) Puedes usar selectores profundos de CSS

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

2) También puede cambiar la encapsulación de vista que está configurada en Emulated como predeterminada, pero puede cambiarse fácilmente a Native que usa la implementación del navegador nativo Shadow DOM, en su caso solo necesita deshabilitarlo

Por ejemplo: `

 import { Component, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'parent', styles: [` .first { color:blue; } .second { color:red; } `], template: ` 
First Second
`, encapsulation: ViewEncapsulation.None, }) export class ParentComponent { constructor() { } }

Si no desea utilizar :: ng-deep, puede hacer esto que parece ser la forma correcta:

 import { ViewEncapsulation } from '@angular/core'; @Component({ .... encapsulation: ViewEncapsulation.None }) 

Y luego, podrá modificar el CSS de su componente sin necesidad de :: ng-deep

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

ADVERTENCIA: tenga cuidado ya que si su componente tiene muchos niños, ¡la CSS que escriba para este componente podría afectar a todos los niños!

Me parece mucho más limpio pasar una variable @INPUT si tiene acceso al código del componente secundario:

La idea es que el padre le cuente al niño cuál debe ser su estado de apariencia y el niño decide cómo mostrar el estado. Es una bonita architecture

SCSS Way:

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

Mejor manera: – usa la variable selected :

      

Propongo un ejemplo para hacerlo más claro, ya que angular.io/guide/component-styles establece:

El combinador descendiente que atraviesa las sombras está en desuso y el soporte se está eliminando de los principales buscadores y herramientas. Como tal, planeamos soltar soporte en Angular (para todos los 3 de / deep /, >>> y :: ng-deep). Hasta entonces :: ng-deep debería ser preferido para una compatibilidad más amplia con las herramientas.

En app.component.scss , importe su *.scss si es necesario. _colors.scss tiene algunos valores de color comunes:

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

Aplicar una regla a todos los componentes

Todos los botones que tengan btn-red clase btn-red serán diseñados.

 @import `./theme/sass/_colors`; // red background and white text :host /deep/ button.red-btn { color: $button_ripple_white_text; background: $button_ripple_red; } 

Aplicar una regla a un solo componente

Se btn-red todos los botones que tengan btn-red clase btn-red en el componente de app-login .

 @import `./theme/sass/_colors`; /deep/ app-login button.red-btn { color: $button_ripple_white_text; background: $button_ripple_red; } 

La respuesta rápida es que no deberías estar haciendo esto, en absoluto. Rompe la encapsulación de componentes y socava el beneficio que obtiene de componentes autónomos. Considere pasar una bandera de apoyo al componente secundario, luego puede decidir cómo representar de manera diferente o aplicar CSS diferentes, si es necesario.

    

Angular está desaprobando todas las formas de afectar los estilos infantiles de los padres.

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