Search code examples
cssangularangular-materialcomponentsencapsulation

Angular change child component style from parent component but not globally


I have created a shared component(<nextgen-table></nextgen-table>) based on Mat-table (Angular Material). While using this component inside a project, discover that I need to change the behavior(width) of the table columns.

I have exported nextgen-table in my other components (let's say X, Y ) where nextgen-table is, of course, a child component.

To change the width of specific columns of the mat-table I have to use something like this:

mat-cell:nth-child(1),
mat-header-cell:nth-child(1) {
    flex: 0 0 40%;
    text-align: left;
} 
mat-cell:nth-child(2),
mat-header-cell:nth-child(2) {
    flex: 0 0 20%;
}

The above CSS code I was implementing in the X.component.css and it was not working because of encapsulation I guess.

After a little bit of search, I have found the solution which worked correctly just by adding the encapsulation: ViewEncapsulation.None in the Component decorator of x.component.ts. After this solution, I was navigating from the component X to the Component Y in which I didn't implement the above CSS code. But the component Y had the first two columns as I wanted only for component X but somehow component Y had also which I didn't want for the component Y.

So my question is how can I update the style of nextgen-table from the parent component which only applies for the parent component and not in the other components.

I have also tried to use

:host(mat-cell:nth-child(1)){
  flex: 0 0 40%;
  text-align: left;
}

:host(mat-header-cell:nth-child(1)) {
    flex: 0 0 40%;
    text-align: left;
}

but nothing happened/changed.

Thanks in advance for the help


Solution

  • You can use the ::ng-deep pseudo class, to specifically target child elements without changing the view encapsultation for the whole component (which would mean that all its rules would leak).

    Note: ::ng-deep has been marked as deprecated for since a few major versions now, but they will not remove suppoprt until they have a workaround.

    parentX.html

    <div class="compContainer">
        <nextgen-table></nextgen-table>
    </div>
    

    parentX.scss

    ::ng-deep .compContainer nextgen-table
    {
        mat-cell:nth-child(1),
        mat-header-cell:nth-child(1) {
            flex: 0 0 40%;
            text-align: left;
        } 
        mat-cell:nth-child(2),
        mat-header-cell:nth-child(2) {
            flex: 0 0 20%;
        }
    }
    

    You could also add your css rules to the global style.scss file.

    //Rules for parent X
    app-parent-componentX .compContainer nextgen-table
    {
        mat-cell...
    }
    
    //Rules for a parent Y
    app-parent-componentY .compContainer nextgen-table
    {
        mat-cell...
    }