18

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;
}
Iancovici
  • 5,574
  • 7
  • 39
  • 57
physicsboy
  • 5,656
  • 17
  • 70
  • 119
  • 1
    If you want to remove the floating label it's fairly easy, check here on their official documentation: https://material.angular.io/components/form-field/overview#floating-label. Regarding the underline color your only option is to change it with CSS. – anteAdamovic Jan 31 '18 at 11:05
  • 1
    the complete guide for theming your application is here https://material.angular.io/guide/theming . Basically a material app should have two main color (primary/accent) and the underline will use the primary color of your theme. hope it helps – Pierre Mallet Jan 31 '18 at 11:22
  • Haven't had chance to look at it or try it out yet. I'm not ignoring you, just a little busy. – physicsboy Jan 31 '18 at 14:15

4 Answers4

54

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
})
A. Morel
  • 9,210
  • 4
  • 56
  • 45
14

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.

David Rinck
  • 6,637
  • 4
  • 45
  • 60
  • 1
    Higher specificity worked for me, but I also needed to use ViewEncapsulation.None on the component I intended to style. Thanks! – Bryan McGrane Jan 05 '19 at 16:00
  • 1
    Thank yo sooo much, this worked for me! I need to add ViewEncapsulation as well :) <3 – raven39 Jul 29 '19 at 17:21
10

From my understanding, both features seem to be in MatFormField.

  1. floatPlaceholder is deprecated, because now it's [floatLabel] for FloatLabelType ('never', 'always', 'auto'), applied using input
  2. 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>
Praveen Soni
  • 771
  • 8
  • 21
Iancovici
  • 5,574
  • 7
  • 39
  • 57
  • According to https://github.com/angular/components/issues/18267, FloatLabelType ('never') is gone (deprecated), and if you want no floating label, just use placeholder instead of mat-label – m-khonsari May 15 '23 at 09:40
0

Here is the FREE ultimate solution.

.mat-form-field input {
    height: 20px;
    transition: height ease-in-out 400ms;
}

.mat-form-field input:focus {
    background-color: red !important;
    height: 50px;
    transition: height ease-in-out 400ms;
}

These are for the borders and should be defined in the main style.css.

.mat-form-field-outline-start,
.mat-form-field-outline-end {
  border-radius: 0px !important;
}

And based on the appearance style of "standard", "outline", and "fill". You will have CSS classes as follows.

.mat-form-field-outline {}

.mat-form-field-fill {}

.mat-form-field-standard {}

To style all buttons, you can use the mat-button-base class.

 .mat-button-base {
        border-radius: 0px !important;

    }

!Important: These styles should be defined in the main style file! Otherwise, they are not applied to the elements!

Ahmet Emrebas
  • 566
  • 6
  • 10