วิธีการสไตล์องค์ประกอบเด็กจากไฟล์ CSS ขององค์ประกอบหลัก?


266

ฉันมีองค์ประกอบหลัก:

<parent></parent>

และฉันต้องการเติมกลุ่มนี้ด้วยองค์ประกอบลูก:

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

แม่แบบ:

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

แม่แบบเด็ก:

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

ตั้งแต่parentและchildเป็นสองส่วนแยกสไตล์ของพวกเขาจะถูกล็อคในขอบเขตของตัวเอง

ในองค์ประกอบหลักของฉันฉันพยายามทำ:

.parent .child {
  // Styles for child
}

แต่.childสไตล์ไม่ได้ถูกนำไปใช้กับchildส่วนประกอบ

ฉันพยายามใช้styleUrlsเพื่อรวมparentสไตล์ชีทของchildองค์ประกอบเข้าด้วยกันเพื่อแก้ไขปัญหาขอบเขต:

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

แต่นั่นไม่ได้ช่วยลองวิธีอื่นโดยดึงchildสไตล์ชีทเข้าไปparentแต่ก็ไม่ได้ช่วยอะไร

ดังนั้นคุณจะกำหนดสไตล์องค์ประกอบลูกที่รวมอยู่ในองค์ประกอบหลักได้อย่างไร



ดูสมบูรณ์กระบวนทัศน์ง่ายวิธีเคล็ดลับฟรีในของฉันคำตอบ
Alexander Abakumov

คำตอบ:


242

อัพเดท - วิธีใหม่ล่าสุด

อย่าทำอย่างนั้นถ้าคุณสามารถหลีกเลี่ยงได้ ดังที่ Devon Sans ชี้ให้เห็นในความคิดเห็น: คุณลักษณะนี้มักจะถูกคัดค้าน

อัพเดท - วิธีที่ใหม่กว่า

จาก Angular 4.3.0 combinartors css ที่เจาะทั้งหมดถูกคัดค้าน ทีมเชิงมุมแนะนำผู้ประสานใหม่::ng-deep (ยังอยู่ในระดับทดลองไม่ใช่วิธีเต็มและสุดท้าย)ดังแสดงด้านล่าง

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


วิธีเก่า ๆ

คุณสามารถใช้encapsulation modeและ / หรือpiercing CSS combinators >>>, /deep/ and ::shadow

ตัวอย่างการทำงาน: 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>      
`

3
ผู้เจาะรวม CSS จะเลิกใช้งานใน Chrome แล้ว
Robin-Hoodie

22
ทีมเชิงมุมวางแผนที่จะยกเลิกการสนับสนุนของ :: ng-deep เช่นกัน จากเอกสารของพวกเขา: "combinator ลูกหลานเงาถูกคัดค้านและการสนับสนุนจะถูกลบออกจากเบราว์เซอร์และเครื่องมือที่สำคัญดังนั้นเราวางแผนที่จะวางการสนับสนุนใน Angular (สำหรับทั้ง 3 จาก / ลึก /, >>> และ :: ng- deep). จนกว่าจะถึงตอนนั้น :: ng-deep ควรเป็นที่ต้องการสำหรับความเข้ากันได้ที่กว้างขึ้นกับเครื่องมือ " angular.io/guide/component-styles#deprecated-deep--and-ng-deep
Devon Sams

5
ตราบใดที่คำตอบนี้ยังคงเป็นที่ยอมรับผู้คนจะเข้าใจผิด :: ng-deepไม่ควรใช้เป็นคะแนน @DevonSams ในความคิดเห็นด้านบน
Kostas Siabanis

1
::ng-deepเลิกใช้แล้วตอนนี้ฉันไม่แนะนำให้ใช้ในแอปพลิเคชันในอนาคต
ร่วงโรย

11
การเลิกใช้สิ่งที่ไม่มีทางเลือกอาจไม่ใช่ทางออกที่ดีที่สุด
tehlivi

56

อัปเดต 3:

::ng-deepเลิกใช้แล้วซึ่งหมายความว่าคุณไม่ควรทำเช่นนี้อีกเลย มันไม่ชัดเจนว่าสิ่งนี้มีผลต่อสิ่งที่คุณต้องการแทนที่สไตล์ในองค์ประกอบลูกจากองค์ประกอบหลัก สำหรับฉันมันดูแปลก ๆ ถ้าสิ่งนี้ถูกลบออกอย่างสมบูรณ์เพราะสิ่งนี้จะส่งผลกระทบต่อสิ่งต่าง ๆ อย่างไรในฐานะห้องสมุดที่คุณต้องการแทนที่สไตล์ในองค์ประกอบไลบรารี

แสดงความคิดเห็นหากคุณมีความเข้าใจในเรื่องนี้

อัปเดต 2:

เนื่องจาก/deep/และตัวเลือกการเจาะเงาอื่น ๆ ทั้งหมดเลิกใช้แล้ว ลดลงเชิงมุม::ng-deepซึ่งควรใช้แทนกันได้กว้าง

UPDATE:

หากใช้ Angular-CLI คุณจำเป็นต้องใช้/deep/แทน>>>มิฉะนั้นจะไม่สามารถใช้งานได้

ORIGINAL:

หลังจากไปที่หน้า Github ของ Angular2 และทำการค้นหา "สไตล์" แบบสุ่มฉันพบคำถามนี้: Angular 2 - innerHTML ใส่สไตล์

ซึ่งบอกว่าจะใช้สิ่งที่เพิ่มเข้ามาใน2.0.0-beta.10ที่>>>และ::shadowตัวเลือก

(>>>) (และเทียบเท่า / ลึก /) และ :: shadow ถูกเพิ่มเข้าไปใน 2.0.0-beta.10 มันคล้ายกับ combinators DOM DOM เงา (ซึ่งเลิกใช้แล้ว) และใช้ได้กับ encapsulation เท่านั้น: ViewEncapsulation.Emulated ซึ่งเป็นค่าเริ่มต้นใน Angular2 พวกเขาอาจใช้งานได้กับ ViewEncapsulation ไม่มี แต่จะถูกละเว้นเพียงเพราะไม่จำเป็น Combinators เหล่านี้เป็นเพียงวิธีการแก้ปัญหาขั้นกลางจนกระทั่งคุณสมบัติขั้นสูงเพิ่มเติมสำหรับการจัดแต่งทรงผมแบบข้ามองค์ประกอบได้รับการสนับสนุน

ดังนั้นเพียงทำ:

:host >>> .child {}

ในparentสไตล์ชีทของไฟล์แก้ไขปัญหาได้ โปรดทราบตามที่ระบุไว้ในใบเสนอราคาข้างต้นโซลูชันนี้เป็นสื่อกลางเท่านั้นจนกว่าจะสนับสนุนสไตล์การจัดองค์ประกอบข้ามขั้นสูงเพิ่มเติม


ดูเหมือนว่าพวกเขากำลังจะยกเลิกการสนับสนุนสำหรับ :: ng-deep angular.io/guide/component-styles#deprecated-deep--and-ng-deep
Jed Richards

42

คุณไม่ควรใช้::ng-deepมันเลิกใช้แล้ว ในเชิงมุมวิธีที่เหมาะสมในการเปลี่ยนรูปแบบขององค์ประกอบของเด็กจากผู้ปกครองคือการใช้encapsulation(อ่านคำเตือนด้านล่างเพื่อทำความเข้าใจกับผลกระทบ):

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

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

จากนั้นคุณจะสามารถแก้ไขรูปแบบ css ของคุณได้โดยไม่จำเป็นต้องใช้จาก :: ng-deep

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

คำเตือน: การทำเช่นนี้จะทำให้กฎ css ทั้งหมดที่คุณเขียนสำหรับส่วนนี้เป็นแบบโกลบอล

ในการ จำกัด ขอบเขตของ css ของคุณให้กับส่วนนี้เท่านั้นให้เพิ่มคลาส css ที่แท็กด้านบนของส่วนประกอบของคุณและวาง css ของคุณ "ข้างใน" แท็กนี้:

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

ไฟล์ Scss:

.my-component {
  // All your css goes in there in order not to be global
}

3
นี่คือคำตอบที่ดีที่สุด IMO ตามที่มันเป็นจริงเป็นทางเลือกที่ทำงานได้ในเร็ว ๆ ::ng-deepนี้เพื่อจะเลิก โดยทั่วไปส่วนประกอบมีตัวเลือกของตัวเองอยู่แล้ว ( <my-component>, <div my-component>ฯลฯ ) ดังนั้นจึงไม่จำเป็นต้องมีแม้แต่องค์ประกอบ wrapper ที่มีคลาสพิเศษ
Alex Walker

@AlexWalker นี่อาจเป็นคำตอบที่ดีที่สุดสำหรับสถานการณ์ของคุณแต่ควรจะพูดถึงเพียงครึ่งเดียวของคำถามของ OP: วิธีนี้ทำให้ CSS สามารถเผยแพร่ตามปกติจากบนลงล่าง แต่โดยอาศัยการทิ้ง encapsulation ทั้งหมดไม่ได้ 'T ขีด จำกัด ที่จัดแต่งทรงผมให้กับเด็กของผู้ปกครองที่เฉพาะเจาะจง หากคุณกำหนดลักษณะลูกของ parent1 หนึ่งวิธีและ children ของ parent2 อีกหนึ่งกฎ CSS เหล่านั้นจะต่อสู้กันในที่ทั้งสองแห่ง ที่สามารถเจ็บปวดใจมึนงง (และ Angular เพิ่ม encapsulation เพื่อหลีกเลี่ยง)
รัฟฟิน

@ruffin นั่นเป็นเหตุผลว่าทำไมผมเพิ่มคำเตือนในคำตอบของฉันที่จะเข้าใจความหมายของการใช้เทคนิคนี้และวิธีการที่ "ตนเองแค็ปซูล" ใช้แท็กด้านบน CSS ในส่วนของคุณ
โตนิโอ

1
@Tonio - ใช่เห็นด้วย ตอบกลับอเล็กซ์โดยตรงมากกว่าคุณ ความเห็นของเขา " ดังนั้นไม่จำเป็นต้องมีองค์ประกอบของเสื้อคลุมที่มีคลาสพิเศษ " ทำให้ฉันกลัวเล็กน้อย อาจจะเป็นสถานการณ์ที่เฉพาะเจาะจงแต่มีเหตุผลที่ทำให้เสียเวลา "เชิงมุม" ที่สนับสนุนการห่อหุ้ม คำตอบนี้เป็นวิธีแก้ปัญหาที่ใช้การได้ในบางกรณี แต่อย่างที่คุณบอกว่าเป็นคำที่อันตรายโดยทั่วไป วิธีการแก้ปัญหาของ MatthewBเช่นกำหนดลักษณะของเด็กในขณะที่ห่อหุ้ม (แต่มันก็ยุ่งเหยิงจริงๆถ้าคุณมีส่วนประกอบของเด็กมากกว่าหนึ่งรุ่น)
ruffin

19

น่าเศร้าที่ปรากฏว่า / deep / selector เลิกใช้แล้ว (อย่างน้อยใน Chrome) https://www.chromestatus.com/features/6750456638341120

ในระยะสั้นจะปรากฏว่ามี (ในปัจจุบัน) ไม่มีวิธีแก้ปัญหาระยะยาวนอกเหนือจากการได้รับองค์ประกอบลูกของคุณเพื่อสิ่งที่มีสไตล์แบบไดนามิก

คุณสามารถส่งวัตถุสไตล์ให้ลูกของคุณและนำไปใช้ผ่านทาง:
<div [attr.style]="styleobject">

หรือถ้าคุณมีสไตล์เฉพาะคุณสามารถใช้สิ่งต่อไปนี้:
<div [style.background-color]="colorvar">

การสนทนาเพิ่มเติมที่เกี่ยวข้องกับสิ่งนี้: https://github.com/angular/angular/issues/6511


16

มีปัญหาเดียวกันดังนั้นหากคุณใช้ angular2-cli กับ scss / sass ใช้ '/ deep /' แทน '>>>' ตัวเลือกสุดท้ายยังไม่รองรับ (แต่ใช้งานได้ดีกับ css)


11

หากคุณต้องการกำหนดเป้าหมายไปยังองค์ประกอบย่อยที่แท้จริงมากกว่าที่คุณควรทำดังต่อไปนี้ ด้วยวิธีนี้หากองค์ประกอบย่อยอื่น ๆ ใช้ชื่อคลาสเดียวกันพวกเขาจะไม่ได้รับผลกระทบ

นักวาง: https://plnkr.co/edit/ooBRp3ROk6fbWPuToytO?p=preview

ตัวอย่างเช่น:

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

หวังว่านี่จะช่วยได้!

codematrix


9

จริงๆแล้วมีอีกหนึ่งตัวเลือก ซึ่งค่อนข้างปลอดภัย คุณสามารถใช้ ViewEncapsulation.None แต่ใส่ลักษณะองค์ประกอบทั้งหมดของคุณลงในแท็ก (aka ตัวเลือก) แต่อย่างไรก็ตามก็ชอบสไตล์โลกมากกว่าและสไตล์ที่ห่อหุ้มอยู่เสมอ

นี่คือตัวอย่าง 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() { }
}

7

มีสองสามตัวเลือกเพื่อให้บรรลุสิ่งนี้ในเชิงมุม:

1) คุณสามารถใช้ตัวเลือก CSS ลึก

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

2) นอกจากนี้คุณยังสามารถเปลี่ยนมุมมองการห่อหุ้มที่ตั้งค่าเป็นจำลองเป็นค่าเริ่มต้น แต่สามารถเปลี่ยนเป็นเนทิฟได้อย่างง่ายดายซึ่งใช้การใช้เบราว์เซอร์เนทีฟ Shadow DOM ในกรณีของคุณคุณต้องปิดการใช้งาน

ตัวอย่างเช่น: `

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

   }
 }

3
จริงๆแล้วมันหมายถึงสไตล์ที่มีผลต่อทั้ง Dom ไม่เพียง แต่องค์ประกอบของเด็ก
Kasper Ziemianek

7

คุณไม่ควรเขียนกฎ CSS สำหรับองค์ประกอบองค์ประกอบลูกในองค์ประกอบหลักเนื่องจากองค์ประกอบเชิงมุมเป็นนิติบุคคลที่มีอยู่ในตัวเองซึ่งควรประกาศสิ่งที่มีอยู่สำหรับโลกภายนอกอย่างชัดเจน หากการเปลี่ยนแปลงเลย์เอาต์ของเด็กในอนาคตสไตล์ของคุณสำหรับองค์ประกอบองค์ประกอบลูกนั้นกระจัดกระจายไปในไฟล์ SCSS ของคอมโพเนนต์อื่นอาจแตกหักได้ง่าย นั่นคือสิ่งที่ViewEncapsulationมีไว้สำหรับในกรณีของ CSS มิฉะนั้นจะเหมือนกันถ้าคุณสามารถกำหนดค่าให้กับเขตข้อมูลส่วนตัวของคลาสบางคลาสจากคลาสอื่น ๆ ในการเขียนโปรแกรมเชิงวัตถุ

ดังนั้นสิ่งที่คุณควรทำคือการกำหนดชุดของคลาสที่คุณสามารถนำไปใช้กับองค์ประกอบโฮสต์เด็กและใช้วิธีการที่เด็กตอบสนองต่อพวกเขา

ในทางเทคนิคสามารถทำได้ดังนี้:

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

กล่าวอีกนัยหนึ่งคุณใช้:hostตัวเลือกหลอกที่จัดทำโดยชุด Angular + ของคลาส CSS เพื่อกำหนดสไตล์ลูกที่เป็นไปได้ในองค์ประกอบลูก จากนั้นคุณมีความสามารถในการทริกเกอร์สไตล์เหล่านั้นจากภายนอกโดยใช้คลาสที่กำหนดไว้ล่วงหน้ากับ<child>องค์ประกอบโฮสต์


ดูเหมือนโซลูชันที่ดีมีไฟล์ parent.component.scss หรือไม่ ถ้าใช่สนใจจะให้มัน?
Manohar Reddy Poreddy

@ManoharReddyPoreddy ไม่ควรใส่สไตล์ในส่วนparent.component.scssที่เกี่ยวข้องกับสไตล์ขององค์ประกอบลูก เป็นจุดประสงค์เดียวของแนวทางนี้ ทำไมคุณต้องparent.component.scss?
อเล็กซานเดอร์ Abakumov

ไม่แน่ใจเพียงแค่รู้ CSS คุณสามารถแบ่งปันโซลูชันเต็มรูปแบบกับ jsbin หรืออื่น ๆ โซลูชันของคุณอาจเป็นทางออกสำหรับทุกคนในอนาคต
Manohar Reddy Poreddy

2
@ManoharReddyPoreddy ฉันขอแนะนำให้คุณลองใช้รหัสเหล่านั้นก่อน จากนั้นหากคุณพบปัญหาใด ๆ คุณจะมีคำถามเฉพาะซึ่งฉันสามารถตอบหรือคำแนะนำในการดูหัวข้อเฉพาะเพื่อทำความเข้าใจวิธีการแก้ไขปัญหาของคุณ ฉันกล่าวถึงViewEncapsulationเพียงเพราะค่าเริ่มต้นคือสิ่งที่นำไปสู่คำถาม OP คุณไม่จำเป็นต้องกำหนดViewEncapsulationรหัสอื่นให้ใช้งานได้
อเล็กซานเดอร์ Abakumov

1
+1 ขอบคุณ จะกลับมาใช้วิธีแก้ปัญหานี้ในอนาคตตัดสินสำหรับ :: ng-deep stackoverflow.com/a/36528769/984471สำหรับวันนี้
Manohar Reddy Poreddy

5

ฉันพบว่ามันสะอาดกว่าการส่งผ่านตัวแปร @INPUTถ้าคุณเข้าถึงรหัสองค์ประกอบลูก:

แนวความคิดคือผู้ปกครองบอกเด็กว่าสถานะของลักษณะที่ปรากฏควรเป็นอย่างไรและเด็กตัดสินใจว่าจะแสดงสถานะอย่างไร มันเป็นสถาปัตยกรรมที่ดี

วิธี SCSS:

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

วิธีที่ดีกว่า: - ใช้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>

2
ยากต่อการบำรุงรักษาโดยเฉพาะอย่างยิ่งสำหรับส่วนประกอบแบบเรียกซ้ำ
Erik Philips

2

ณ วันนี้ (9 เชิงมุม) เชิงมุมใช้เงา DOMที่จะแสดงส่วนประกอบเป็นองค์ประกอบ HTML ที่กำหนดเอง หนึ่งในวิธีที่สง่างามสไตล์องค์ประกอบที่กำหนดเองเหล่านั้นอาจจะใช้ตัวแปร CSS ที่กำหนดเอง นี่คือตัวอย่างทั่วไป:

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>

ดังที่เราเห็นจากโค้ดด้านบนเราสร้างองค์ประกอบที่กำหนดเองเช่นเดียวกับ Angular สำหรับเรากับทุกองค์ประกอบแล้วเราจะแทนที่ตัวแปรที่รับผิดชอบสีพื้นหลังภายในเงารากขององค์ประกอบที่กำหนดเองจากขอบเขตทั่วโลก .

ในแอพเชิงมุมนี่อาจเป็นสิ่งที่ชอบ:

parent.component.scss

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

เด็กที่ element.component.scss

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

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

0

คำตอบอย่างรวดเร็วคือคุณไม่ควรทำสิ่งนี้เลย มันแบ่งการห่อหุ้มส่วนประกอบและทำลายประโยชน์ที่คุณได้รับจากส่วนประกอบที่มีในตัวเอง พิจารณาผ่านการตั้งค่าสถานะ prop ไปยังคอมโพเนนต์ของเด็กจากนั้นสามารถตัดสินใจเองวิธีการแสดงผลที่แตกต่างกันหรือใช้ CSS ต่าง ๆ ถ้าจำเป็น

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

เชิงมุมลดค่าลงทุกวิธีในการส่งผลกระทบต่อรูปแบบของเด็กจากผู้ปกครอง

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


พวกเขาได้กล่าวไว้อย่างชัดเจนในเอกสารของพวกเขาว่าพวกเขากำลังทำอยู่ในที่สุดซึ่งฉันคิดว่าพวกเขาจะทำ ฉันเห็นด้วยแม้ว่าจะไม่เกิดขึ้นทุกเวลาเร็ว ๆ นี้
Jed Richards

ดังนั้นพวกเขาจะทำให้ห้องสมุดวัสดุของพวกเขาไร้ประโยชน์ ฉันไม่เคยใช้ชุดรูปแบบเริ่มต้นในห้องสมุดใด ๆ เนื่องจากลูกค้าแต่ละรายต้องการการออกแบบของตัวเอง โดยปกติคุณเพียงแค่ต้องการฟังก์ชั่นของส่วนประกอบ ฉันไม่สามารถพูดได้ว่าฉันเข้าใจตรรกะโดยรวมของพวกเขาหลังการตัดสินใจครั้งนี้
Chrillewoodz

0

ฉันยังมีปัญหานี้และไม่ต้องการใช้โซลูชันที่เลิกใช้ดังนั้นฉันจึงลงเอยด้วย:

ใน parrent

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

องค์ประกอบลูก

@Input() ContainerCustomStyle: string;

ในเด็กใน html div

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

และในรหัส

constructor(private sanitizer: DomSanitizer) {  }

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

ทำงานเหมือนที่คาดไว้และไม่ควรเลิกใช้;)


! ที่น่าสนใจ ฉันลงเอยด้วยสิ่งที่คล้ายกัน (ตอนนี้) คุณได้รับ DomSanitizer จากที่ไหน แก้ไข: พบมัน: angular.io/api/platform-browser/DomSanitizer
Zaphoid

อ๋อใน v7 มันเป็นแบบดั้งเดิมคุณแค่ขอฉีดมันลงในคอนสตรัคเตอร์ ;), ในรุ่นเก่าฉันไม่รู้ว่ามันมีอยู่ - ฉันเริ่มต้นจาก v7;)
d00lar

0

เนื่องจากการอัปเดตอินเทอร์เน็ตฉันได้พบกับโซลูชัน

ประการแรกบางประการ

  1. ยังไม่ทำ เพื่อความกระจ่างแจ้งฉันจะไม่วางแผนเกี่ยวกับองค์ประกอบย่อยที่อนุญาตให้คุณจัดวางองค์ประกอบเหล่านั้น SOC หากคุณในฐานะผู้ออกแบบองค์ประกอบต้องการอนุญาตให้ใช้สิ่งนี้คุณก็ยิ่งมีพลังมากขึ้น
  2. หากลูกของคุณไม่ได้อยู่ในเงามืดแล้วนี่จะไม่เหมาะกับคุณ
  3. หากคุณต้องสนับสนุนเบราว์เซอร์ที่ไม่มีเงาโดมิโนนี่ก็ไม่ได้ผลสำหรับคุณ

ขั้นแรกให้ทำเครื่องหมายการห่อหุ้มส่วนประกอบของลูกของคุณเป็นเงาเพื่อให้แสดงผลในเงาของom ประการที่สองเพิ่มแอตทริบิวต์ส่วนหนึ่งให้กับองค์ประกอบที่คุณต้องการให้ผู้ปกครองมีสไตล์ ในสไตล์ชีทส่วนประกอบของผู้ปกครองคุณสามารถใช้วิธี :: part () เพื่อเข้าถึง


-1

ฉันเสนอตัวอย่างเพื่อให้ชัดเจนยิ่งขึ้นเนื่องจากangular.io/guide/component-stylesกล่าวว่า:

Combinator ที่เรียงตามลำดับเงาถูกคัดค้านและการสนับสนุนจะถูกลบออกจากเบราว์เซอร์และเครื่องมือที่สำคัญ ดังนั้นเราจึงวางแผนที่จะลดการสนับสนุนใน Angular (สำหรับทั้ง 3 ของ / deep /, >>> และ :: ng-deep) จนกว่าจะถึงตอนนั้น :: ng-deep ควรเป็นที่ต้องการสำหรับความเข้ากันได้ในวงกว้างกับเครื่องมือ

เมื่อapp.component.scssนำเข้าของคุณ*.scssหากจำเป็น _colors.scssมีค่าสีทั่วไป:

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

ใช้กฎกับส่วนประกอบทั้งหมด

ปุ่มทั้งหมดที่มี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;
}

ใช้กฎกับองค์ประกอบเดียว

ปุ่มทั้งหมดที่มีbtn-redคลาสในapp-loginส่วนประกอบจะถูกจัดรูปแบบ

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

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

-1

ฉันแก้ไขมันนอกแองกูลาร์ ฉันได้กำหนด scss ที่ใช้ร่วมกันซึ่งฉันกำลังนำเข้าสู่ลูก ๆ ของฉัน

shared.scss

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

child.scss

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

วิธีการนำเสนอของฉันเป็นวิธีการแก้ปัญหาที่ OP ได้ถามไป ดังที่กล่าวไว้หลายครั้ง :: ng-deep,: ng-host จะได้รับการคิดค่าเสื่อมราคาและการปิดการใช้งานการห่อหุ้มเป็นเพียงการรั่วไหลของรหัสมากเกินไปในมุมมองของฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.