Angular: override child components without ng-deep

Vugar Abdullayev
3 min readJul 21, 2023

--

Midjourney

Not a member of Medium? Read this article for free here.

Assume you want to modify styles of child components but

✅ You want clean and native approach so you don’t want to use ng-deep

✅ You want to avoidhost-selector ensuring that your child component styles remain unbloated.

The idea is that nested components should be able to be styled natively but they should not be modified. In other words: Open Closed Principle of SOLID.

💎 Live Demo: https://stackblitz.com/edit/stackblitz-starters-lvddww

The Objective:

Let’s consider a practical scenario: we have a post-card component that we want to style. Here’s what the current HTML and SCSS structure looks like:

Post Card Component

The HTML structure:

<div class="post">
<h3 class="post__title">{{ title }}</h3>
<button class="post__btn">
<a [href]="link"> Read More</a>
</button>
</div>

The SCSS structure:

:host {
display: block;
}

.post {
display: flex;
flex-direction: row;
align-items: center;
width: 600px;
box-shadow: 0px 1px 7px rgb(34 35 58 / 20%);
background: #fff;

&__title {
padding: 10px;
font-size: 1.8rem;
font-weight: 600;
margin: 0px;
color: #000;
}

&__btn {
background: #f1c40f;
border-radius: 4px;
border: 0;
padding: 0 16px 0 16px;
height: 36px;
margin-left: 10px;
cursor: pointer;
a {
text-decoration: none;
}
}
}

We want to transfer post-card styles to look like below:

Post Card new styles

Solution 🚀:

Our aim is to transform the style of the post-card component to resemble the above design. But instead of hard coding the styles of the nested components, we’ll use CSS variables, allowing us to manipulate these variables from the parent component.

Here’s the new and improved SCSS structure of post-card:


:host {
display: block;
}

.post {
display: flex;
flex-direction: row;
align-items: center;
width: 600px;
box-shadow: 0px 1px 7px rgb(34 35 58 / 20%);
background: var(--post-card-background, #fff);

&__title {
padding: 10px;
font-size: var(--post-card-title-font-size, 1.8rem);
font-weight: 600;
margin: 0px;
color: var(--post-card-title-color, #000);
}

&__btn {
background: var(--post-card-btn-background, #f1c40f);
border-radius: 4px;
border: 0;
padding: 0 16px 0 16px;
height: 36px;
margin-left: 10px;
cursor: pointer;
a {
text-decoration: none;
}
}
}

So let’s explain a bit further.

background: var(--post-card-background, #fff);

This above code says: Use var( — post-card-background) as a background color but IF that css variable does not exist use default fallback (#fff) 😎.

Now in ANY parent component we can override those css variables. So in our parent post-list component.

.post-card {
--post-card-btn-background: #27ae60;
--post-card-background: #34495e;
--post-card-title-color: #fff;
}

and HTML structure:

<div class="post-list">
<post-card class="post-card"/>
</div>

That’s all. I tried to keep it short. Hope you find it useful 🙂.

💎 Source Code: https://stackblitz.com/edit/stackblitz-starters-lvddww

About me: I am a junior front-end developer.

Twitter: https://twitter.com/Vugar005

You can also check out my other blogs or projects 💎:

--

--