12

I am using Material 2 <md-input-container> in my Angular component. I want to override one of the classes e.g. .mat-input-wrapper defined in Angular Material. But I want to override only in that component and the override should not effect other components in the page.

Here is the screenshot of the rendered element:Rendered md-input-container

nullDev
  • 11,170
  • 8
  • 34
  • 52

6 Answers6

19

As @Dylan pointed out, you have to use /deep/ to alter the CSS within the child compoenets. Here is the answer I was looking for:

:host /deep/ md-input-container .mat-input-wrapper

nullDev
  • 11,170
  • 8
  • 34
  • 52
  • I was looking for this all over the place! I really think this solution should be written in a prominent place in the docs. – Gal Talmor Jun 24 '17 at 19:56
  • 3
    `/deep/` and all aliases of it are now deprecated. No equivalent solution is available. Rumor is they are waiting for w3c to create a solution. – Kevin Beal Jul 02 '18 at 21:39
  • That may be true, but I'm still seeing that this solution works in an Angular 7.1.3 solution with Angular Material 7.1.1 – Whit Waldo Dec 17 '18 at 08:24
  • Preferred usage is ::ng-deep - even though this will be depreciated eventually it has best compatibility for short term use. From NG Docs: The shadow-piercing descendant combinator is deprecated and support is being removed from major browsers and tools. As such we plan to drop support in Angular (for all 3 of /deep/, >>> and ::ng-deep). Until then ::ng-deep should be preferred for a broader compatibility with the tools. – aoakeson Feb 07 '19 at 00:26
3

If you are using SCSS try ::ng-deep

::ng-deep { 
       .sample {
         // style
         color: green;
       }
    }
Deepu Reghunath
  • 8,132
  • 2
  • 38
  • 47
1

There's no need to wrap with <div class="someCssClassName">. Rather, to style an Angular Material element like the title of a card..

<mat-card>
   <mat-card-title>
      {{title}}
   </mat-card-title>
</mat-card>

CSS:

mat-card mat-card-title {
   color: red;
}

Applying this to another 'child' element like <mat-card-content>

mat-card mat-card-content,
mat-card mat-card-title {
   color: red;
}

Using VS Code, hovering in the CSS editor will reveal detail of how this CSS will render. In this example, <mat-card>...<mat-card-title>

Of course, if you have multiple uses of the card in a single component, then you will need to make the distinction with a CSS class name adding the class="card-style-1" to the element itself, like <mat-card class="card-style-1".

CSS:

mat-card.card-style-1 mat-card-content,
mat-card.card-style-1 mat-card-title {
   color: red;
}

The alternative to this is to create individual components specific to the uses of different cards, styling each as required.

Adam Cox
  • 3,341
  • 1
  • 36
  • 46
1

The easiest approach I would suggest for SCSS is:

  1. You can copy the class name of property and override it in style.scss so it will work.

  2. Create a @mixin in new SCSS file and override all properties u want. then import this @mixin in style.scss. It is more cleaner approach.

EDIT: More easy and clear way to override the default css for particular component only:

  1. Open index.html and assign one unique attribute to body, as I have added override

    <body override>
     <app-root>
        <loading-screen></loading-screen>
     </app-root>
    </body>
    
  2. Suppose you want to override a <md-input-container> css properties for Employee component which has selector app-employee.

  3. Open style.css and create override css like below.

    [override] app-employee .mat-input-container {
    // add your custom CSS properties 
    // this will apply only a particular component 
    }
    
  4. Run and Enjoy

tripleee
  • 175,061
  • 34
  • 275
  • 318
Vitron
  • 311
  • 2
  • 6
1

The problem with ::ng-deep is, it will apply the style across all the pages and all the components. Meaning its a dirty approach. A better way to do this, is to wrap with a custom class and style the element in your styles.scss/styles.css

Example: As asked in the question. To override a .mat-input-wrapper, wrap your element with your custom class like:

<md-input-container class='big-input'>. Then in

styles.scss:

.big-input .mat-input-wrapper {
   height : 200px;
}

add !important if necessary.

Deb
  • 5,163
  • 7
  • 30
  • 45
-1

The preferred solution probably would be to define the styles in your own Material theming style sheet. The use of /deep/ is deprecated (Angular V 4.3): https://angular.io/guide/component-styles#special-selectors

You can now use ::ng-deep at as an alternative to defining your own theming style sheet.

However, using the ::ng-deep can influence the use Material icons negatively again when using it to override a default font family (as Material Icons is a font-family as well)

  • @DennisSmolek no its not. https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep . You should use ng-deep because there is no replacement for similar functionality. They have just amrked it as deprecated to inform developers that it will be changed after there is general functionality in css itself. So you should use ::ng-deep if needed. – Janne Harju Sep 30 '19 at 07:37