0

I'm using ViewEncapsulation.None to override the material styles of my custom mat-form-field component that I use in my login page. However, I have reached a scenario where down the line in the app, whenever I use another mat-form-field in another component, some styles that are used in the login page mat-form-field are inherited, leaving the current component styles with no effect.

You can see what I mean below. This is the first instance where I use the first mat-form-field:

enter image description here

But when I use a mat-form-field again, in another component, some styles are ignored, like so:

enter image description here

When in reality, this would be the desired result:

enter image description here

What can I do to override these inherited styles?

Thanks in advance.

1 Answer 1

1

If you want your styles to only apply to the custom field, rather than any direct usages of mat-form-field.

You can set up your custom field with normal view encapsulation (as long as you aren't using the shadow-dom)

Then you use ::ng-deep to pierce the encapsulation.

For example one method I often use for selectors that don't select anything rendered by the component itself (ones that won't have the hash code attribute for the view encapsulation) is to select the :host element and then do a descendant combinator from there with ::ng-deep.

:host ::ng-deep .mat-form-field {
 background: pink;
}

Note, you might need to play around with things a little and double check which styles are/aren't getting applied via the dev tools.


Background Information

:host selects the host element. This element is what angular automatically creates as the parent of all components. It'll be kebob case component name and would be selectable via :host which gets the current component's host element (via attribute selector), or it can generally be selected via component-name {} as if it is a normal element.

The host element is what classes and inline styles get applied to, because Angular knows they are always there. There is also no way to avoid having a host element in Angular (there was a way back in angular.js)

::ng-deep as mentioned is "deprecated". The problem is... there's no replacement for it. Working with other libraries while trying to encapsulate some changes, it's easy enough to keep using ng-deep. Google has never given a removal version for it despite being "deprecated", and there have been several major versions since that deprecation. From an Angular issue, it looks like they don't plan to remove ng-deep until there's a replacement.

That being said, if you really don't want to use ng-deep, then you can remove ViewEncapsulation and replace the :host ::ng-deep by selecting the host element yourself via the host element's element selector. For example, component-name .mat-form-field{} will select .mat-form-field class only when a child of the host element component-name.

Sign up to request clarification or add additional context in comments.

8 Comments

That seemed to solved my problem. I was aware of ng::deep but was a little hesitant on using it since it is deprecated but the frustrations of using ViewEncapsulation.None might just ecplise the worry of using a deprecated combinator. Btw, I don't really understand the :host part, could you explain? Should I always use it with ::ng-deep?
@ManuelBrás, hopefully this answers all your questions!
Thanks for the awesome answer! ::ng-deep seems to make my life easier right now. Also, is there a way I can group all the material styles I'm using under a single ::ng-deep? Would be cleaner that way, if possible.
I believe that using scss/less, you can use nested classes and it'll work fine. :host ::ng-deep{ .mat-form-field:{ } } should work in theory.
Try passing in a relevant class to the mat form field, and using those to style off of instead of the more generic MUI classes. That way you are using completely different classes as a base between the login form and the status form.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.