Home > Net >  Custom style material input without ng deep/!important/
Custom style material input without ng deep/!important/

Time:07-28

I need to customise material input, specifically make it round with border radius. I've found a solution on how to do this by adding a class "custom-search" to the mat-form-field and applying the border radius in the global stlysheet like so

.custom-search .mat-form-field-outline .mat-form-field-outline-start {
  border-radius: 100px 0 0 100px;
  min-width: 100px;
}

.custom-search .mat-form-field-outline .mat-form-field-outline-end {
  border-radius: 0 100px 100px 0;
}

However the background is not rounded, I managed to figure out the css classes that affect the background but changing it changes all the mat-form-fields in the app, and if I add my custom class it doesn't work.

 .mat-form-field-appearance-outline:not(.mat-form-field-disabled) .mat-form-field-wrapper .mat-form-field-flex .mat-form-field-outline {
  border-radius: 100px;
}

enter image description here

I do not want to use deprecated methods such as ng deep, !important, or turning off view encapsulation.

CodePudding user response:

There is documentation about component customization. You can pick what it suits best for your use case in the Customizing Angular Material component styles guide.

CodePudding user response:

I feel that there're many ways to get it, and this is not the better way, but in styles.css

.search.mat-form-field-appearance-outline .mat-form-field-outline-start{
  width: 50px;
  border-radius: 50px 0 0 50px;
  background:white
}
.search.mat-form-field-appearance-outline .mat-form-field-outline-end{
  width: 50px;
  border-radius: 0 50px 50px 0;
  background:white;
}
.search.no-label.mat-form-field-appearance-outline .mat-form-field-outline-end
{
  border-radius:50px;
  border-left:1px solid;
  background:white;
}
.search.no-label.mat-focused.mat-form-field-appearance-outline .mat-form-field-outline-end,
.search.no-label.mat-form-field-appearance-outline .mat-form-field-flex:hover .mat-form-field-outline-end
{
  border-left:2px solid;

}

.search.no-label.mat-form-field-appearance-outline .mat-form-field-outline-start,.search.no-label.mat-form-field-appearance-outline .mat-form-field-outline-gap
{
  min-width: 0;
  border:none;
  border-radius:0;
}

.search .mat-form-field-outline-gap{
  background:white
}

See that you use

   //If the formField include a `mat-label`
   <mat-form-field appearance="outline" >
   ...
   </mat-form-field>

   //If the formField NOT include a `mat-label`
   <mat-form-field appearance="outline" >
   ...
   </mat-form-field>

stackblitz

CodePudding user response:

::ng-deep

While it is true that ::ng-deep is shown as deprecated in angular and your IDE will show some warning about it, there is currently no real alternative. Nor is there any foresight at when there will be, or about when there will be any other changes to ::ng-deep other than a deprecation.

As mentioned in the other answer you could change material styling in the styles.scss. However that would still break encapsulation as that file is for global styling. Therefor you should only use it if you want to change the styling for that element everywhere it is used in the project.

:host

However, you can keep encapsulation in tact by using :host in the stylesheet at the component level. Angular already mentions as much in the same warning it tells you about the deprecation.

Just use :host right before using ::ng-deep in the stylesheet of your component. This way the styling is only applied to component to which the stylesheet belongs to. Unfortunately this doesn't get rid of the deprecation warning.

For example:

:host ::ng-deep .custom-search .mat-form-field-outline .mat-form-field-outline-start {
  border-radius: 100px 0 0 100px;
  min-width: 100px;
}

Until things change (if ever) I'd go with Angulars recommendation to do it this way, and just ignore the deprecation warning, as there is no alternate solution to change styling of nested components of which you can't directly alter the source.

!important

Most of materials styling can be addressed without the use of important, although some of the styling requires it to be properly overridden. (For example some ripple effects if I recall right.) I'm afraid there's no real way around that.

  • Related