tutorial tipos posicionar posicionamiento hojas externas estilo ejemplos div css angular angular-components

tipos - ¿Cómo diseñar los componentes secundarios del archivo CSS del componente principal?



tipos de hojas de estilo en html (14)

Tengo un componente padre:

<parent></parent>

Y quiero llenar este grupo con componentes secundarios:

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

Plantilla principal:

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

Plantilla hijo:

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

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

En mi componente principal intenté hacer:

.parent .child { // Styles for child }

Pero los estilos .child no se aplican a los componentes child .

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

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

Pero eso no ayudó, también lo intentó de la otra manera al buscar la hoja de estilo child en parent pero eso tampoco ayudó.

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


Actualización: la forma más nueva

No lo hagas, si puedes evitarlo. Como Devon Sans señala en los comentarios: es muy probable que esta característica esté en desuso.

Actualización: nueva forma

Desde Angular 4.3.0 , todos los combinadores de piercing css quedaron en desuso. El equipo angular introdujo un nuevo combinador ::ng-deep (aún está en el nivel experimental y no en la forma 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 <parent> //blue <child></child> //orange <child class="class1"></child> //yellow <child class="class2"></child> //pink </parent> `

Vieja forma

Puede utilizar 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 <parent> //blue <child></child> //orange <child class="class1"></child> //yellow <child class="class2"></child> //pink </parent> `


En realidad hay una opción más. Lo cual es bastante seguro. Puede usar ViewEncapsulation. NINGUNO PERO ponga todos los estilos de sus componentes en su etiqueta (también conocido como selector). Pero de todos modos, siempre prefiero un estilo global más estilos encapsulados.

Aquí está el ejemplo modificado 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() { } }


Hay algunas opciones para lograr esto en Angular:

1) Puedes usar selectores css profundos

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

2) También puede cambiar la encapsulación de vista que está configurada como Emulada por defecto, pero puede cambiarse fácilmente a Nativo que usa la implementación del navegador nativo de DOM DOM, en su caso solo necesita deshabilitar

Por ejemplo: `

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


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 obtienes de los componentes autónomos. Considere pasar una bandera de apoyo al componente hijo, entonces puede decidir por sí mismo cómo renderizar de manera diferente o aplicar CSS diferente, si es necesario.

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

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

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


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

En resumen, parece que (actualmente) no hay una solución a largo plazo que no sea lograr que su componente hijo estilice las cosas dinámicamente.

Puede pasar un objeto de estilo a su hijo y aplicarlo a través de:
<div [attr.style]="styleobject">

O si tiene un estilo específico, puede usar algo como:
<div [style.background-color]="colorvar">

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


Lo he resuelto fuera de Angular. He definido un scss compartido que estoy importando a mis hijos.

shared.scss

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

child.scss

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

Mi enfoque propuesto es una forma de resolver el problema que el OP ha preguntado. Como se mencionó en varias ocasiones, :: ng-deep,: ng-host se depreciará y, en mi opinión, deshabilitar la encapsulación es una pérdida de código.


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 dice al niño cuál debería ser su estado de apariencia, y el niño decide cómo mostrar el estado. Es una bonita arquitectura

Manera SCSS:

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

Mejor manera: - use 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>


No debe escribir reglas CSS para elementos de un componente secundario en un componente primario, ya que un componente angular es una entidad autónoma que debe declarar explícitamente lo que está disponible para el mundo exterior. Si el diseño secundario cambia en el futuro, sus estilos para los elementos de ese componente secundario dispersos en los archivos SCSS de otros componentes podrían romperse fácilmente, haciendo que su estilo sea muy frágil. Para eso es ViewEncapsulation en el caso de CSS. De lo contrario, sería lo mismo si pudiera asignar valores a campos privados de alguna clase desde cualquier otra clase en Programación Orientada a Objetos.

Por lo tanto, lo que debe hacer es definir un conjunto de clases que pueda aplicar al elemento host secundario e implementar cómo responde el niño a ellas.

Técnicamente, se podría hacer de la siguiente manera:

// 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 otras palabras, utiliza :host pseudo-selector de :host proporcionado por Angular + conjunto de clases CSS para definir posibles estilos secundarios en el propio componente secundario. Luego tiene la capacidad de activar esos estilos desde el exterior aplicando clases predefinidas al elemento host <child> .


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

El combinador descendente que atraviesa las sombras está en desuso y el soporte se está eliminando de los principales navegadores y herramientas. Como tal, planeamos eliminar el soporte en Angular (para los 3 de / deep /, >>> y :: ng-deep). Hasta entonces :: ng-deep debería preferirse 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

Se btn-red todos los botones que tengan btn-red clase btn-red .

@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; }


Si desea estar más orientado al componente secundario real de lo que debería, haga lo siguiente. De esta manera, 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: ` <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 {}

¡Espero que esto ayude!

codematrix


Si no desea usar :: 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 formato 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 hijos, ¡el CSS que escriba para este componente podría afectar a todos los hijos!


También tuve este problema y no quería usar una solución obsoleta, así que terminé con:

en padres

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

componente hijo

@Input() ContainerCustomStyle: string;

en niño en html div

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

y en código

constructor(private sanitizer: DomSanitizer) { } GetStyle(c) { if (isNullOrUndefined(c)) { return null; } return this.sanitizer.bypassSecurityTrustStyle(c); }

funciona como se esperaba y no debe ser desaprobado;)


Tuve el mismo problema, por lo 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).


ACTUALIZACIÓN 3:

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

Comenta si tienes alguna idea sobre esto.

ACTUALIZACIÓN 2:

Dado que /deep/ y todos los demás selectores de perforación de sombras ahora están en desuso. Angular cayó ::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 innerHTML

Que decía usar algo que se agregó en 2.0.0-beta.10 , los selectores de ::shadow >>> y ::shadow .

(>>>) (y el equivalente / deep /) y :: shadow se agregaron en 2.0.0-beta.10. Son similares a los combinadores CSS DOM de sombra (que están en desuso) y solo funcionan con encapsulación: ViewEncapsulation.Emulated, que es el valor predeterminado en Angular2. Probablemente también funcionen con ViewEncapsulation. Ninguno, 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.

Entonces simplemente haciendo:

:host >>> .child {}

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