Styling child component from a parent in Angular
Tags: angular, css, basics
Published: 2021-03-01 20:47:31

---
title: Styling child component from a parent in Angular
published: true
description: Short example of how to style a child component from the parent scope
canonical_url: "https://geodev.me/blog/styling-child-component-from-parent-in-angular/"
tags: 
- angular
- css
- basics
//cover_image: https://direct_url_to_image.jpg
---
Angular provides a modular design that encourages the developer to create separate components with its own logic and styles. This approach has many advantages, but it can cause some problems to solve. In this post, I'd like to show how to solve a problem with styling inheritance in Angular.

## The problem

Let's create few components and apply styles to them.

#### `parent.template.html`

```html
<div class="parent__container">
  <app-child></app-child>
</div>
```

### `parent.component.css`

```css
.parent__container {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: peru;
  width: 300px;
  height: 300px;
}
```

### `child.template.html`

```html
<div class="child__container"></div>
```

### `child.component.css`

```css
.child__container {
  background-color: green;
  width: 150px;
  height: 150px;
}
```

This is how it looks. A Very simple markup and the result.

![Green square](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jecn3qyd5l5mw9idmstg.png)

Now, imagine the situation where we want to style the child component basing on the action in the parent. A new css class is added to the parent component, and based on this class we want to change the styling of the container that's inside it.

### `parent.component.css`

```css
.parent__container {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: peru;
  width: 300px;
  height: 300px;
}

.parent__container.alert .child__container {
  background-color: darkred;
}
```

The inner `div` should change the `background-color` property to `darkred` now. But it does not. If we inspect the elements with the developer tools we notice that styles to the `child__container` class are not applied.

![Devtools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hf5up9qnsivep7m3hcwg.png)

## The solution
This is when the `encapsulation` of the property comes in. By default, all Angular components styles are encapsulated. This means that they apply **only** to the component itself. If we try to style the css classes that are outside the component, they won't be applied. 

The simplest solution for this problem is to set the `encapsulation` property to `ViewEncapsulation.None` in the component.

### `parent.component.ts`

```javascript
import { Component, OnInit, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class ParentComponent implements OnInit {
  constructor() {}

  ngOnInit(): void {}
}
```

Now the styles are no more encapsulated and the result of our manipulation is exactly what we wanted:

![Dark red square](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8lkt4i4mf6tvrq2b5jte.png)

However, this solution has a serious downside. The styles from the `parent` component crossed component boundaries and are global now. If there are more elements with the same classes, the styles will be applied to these elements. This may cause unexpected behavior and we should use this solution carefully.

## Using `::ng-deep`

Luckily, there's a better solution to this problem. Angular provides the `::ng-deep` pseudo-class. Using it will disable the encapsulation for **that particular** rule. If we use any selector with this pseudo-class, it will become a global style. But, compared to the previous solution, only the selector and its descendants will be applied in the global scope. 
Here's how to use it in our example:

### `parent.component.css`
```css
::ng-deep .parent__container {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: peru;
  width: 300px;
  height: 300px;
}

.parent__container.alert .child__container {
  background-color: darkred;
}
```

That's it. The `::ng-deep` selector will target every element inside the `parent__container` element. Using it along with the BEM css class naming convention in your project should be enough to prevent the styles "leaking" from the outside of the component. 

The last solution in our case is to put the styles to `styles.css` file in the `src` directory of the Angular project.

## Conslusion

It is possible to spread css styles outside of the Angular component. However, it may cause some unexpected styling issues so try to reduce the usage of this approach. If there's a need to apply styles for the descendant elements, use the `::ng-deep` pseudo-class.