I have a mat-form-field with input that I am wanting to add a custom style to, however I cannot find any documentation regarding this on the official Angular Material website.
My eventual goal is to:
- Change the underline colour after the input box is selected
- Remove the floating label (if possible - I know this was a feature but now deprecated).
I'm not the most adept with Angular just yet, but if things need changing in JS, then I can always give it my best shot.
I just need a little guidance.
Current Code:
<form class="search-form">
<mat-form-field class="example-full-width">
<input class="toolbar-search" type="text" matInput>
<mat-placeholder>Search</mat-placeholder>
<mat-icon matSuffix style="font-size: 1.2em">search</mat-icon>
</mat-form-field>
</form>
Current CSS:
// Change text colour when inputting text
.toolbar-search, mat-placeholder {
color: white;
}
// Changes the underline and placeholder colour before input is selected
/deep/ .mat-input-underline {
background-color: white;
}
From my understanding, both features seem to be in MatFormField.
- floatPlaceholder is deprecated, because now it's
[floatLabel]
for FloatLabelType ('never', 'always', 'auto'
), applied using input
- You can change the color of the underline with input
[color]
, however you can only select colors from your theme ('primary', 'accent', 'warn'
). For more on how to setup the theme go to their website here,
<form class="search-form">
<mat-form-field class="example-full-width"
floatLabel="never" color="primary">
<input class="toolbar-search" type="text" matInput placeholder="search">
<mat-icon matSuffix style="font-size: 1.2em">search</mat-icon>
</mat-form-field>
</form>
For change the styles of material inputs with scss:
Standard:
::ng-deep .mat-form-field {
.mat-input-element {
color: slategray;
}
.mat-form-field-label {
color: slategray;
}
.mat-form-field-underline {
background-color: slategray;
}
.mat-form-field-ripple {
background-color: slategray;
}
.mat-form-field-required-marker {
color: slategray;
}
}
Focused: (when selected)
::ng-deep .mat-form-field.mat-focused {
.mat-form-field-label {
color: #ff884d;
}
.mat-form-field-ripple {
background-color: #ff884d;
}
.mat-form-field-required-marker {
color: #ff884d;
}
.mat-input-element {
color: #ff884d;
}
}
Invalid:
::ng-deep .mat-form-field.mat-form-field-invalid {
.mat-input-element {
color: #ff33cc;
}
.mat-form-field-label {
color: #ff33cc;
.mat-form-field-required-marker {
color: #ff33cc;
}
}
.mat-form-field-ripple {
background-color: #ff33cc;
}
}
DEMO
you can also use ViewEncapsulation.None
to avoid ::ng-deep
which is deprecated:
import { ViewEncapsulation } from '@angular/core';
@Component({
...
encapsulation: ViewEncapsulation.None
})
You can use the css selector you use below:
/deep/ .mat-input-underline {
background-color: white;
}
The /deep/ combinator is slated for deprecation in Angular, so its best to do without it. Unfortunately, the .mat-input-underline from Angular Material is highly specified, which makes it very difficult to override without using /deep/
The best way I have found is to use an ID, which allows you a higher specificity compared to the default Angular Material styles.
<form id="search-form" [formGroup]="form" (ngSubmit)="submit()">
<mat-form-field>
<mat-placeholder class="placeholder">Search</mat-placeholder>
<input type="text" class="toolbar-search" matInput formControlName="search">
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
Then, your 'search-form' id can be used to target the input. You can't target the mat-form-field-underline in the component.scss without breaking your view encapsulation. It's easier to do this at the global level, by adding this to your global.scss
global.scss:
#search-form {
.mat-form-field-underline {
background-color: $accent;
}
.mat-form-field-ripple {
background-color: $accent;
}
.placeholder {
display: none;
}
}
I hope the Angular Material team pulls back their specificity in the future, because currently there's no easy way to override their defaults.