Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't override the angular material theme with my css properties

I am using Angular 6.0.8 with Angular Material theme version 6.4.0

Whenever I try to slightly modify the material theme, it never works, as I always find the material theme properties to overwrite my CSS properties as follows:

currentColor   .mat-input-element (material theme)
initial        input, textarea, select, button (user agent stylesheet)
#1072BA        .English
#1072BA        .English
#1072BA        body

Only the first property is applied (the rest are striked through)

I have tried multiple variations to solve this but none worked (like using important or changing the order of importing the themes)

So what is the proper way to change small things in the material theme & the user stylesheet? (to make this English rule applied for example)

My styles.scss is as follows, it works well only what overrides the Material theme like colors & fonts does not work:

@import '~@angular/material/prebuilt-themes/indigo-pink.css';

/* You can add global styles to this file, and also import other style files */

/* prevent clicking in the wizard nav header */
.mat-horizontal-stepper-header{
  pointer-events: none !important;
}

@font-face {
  font-family: 'Material Icons';
  font-style: normal;
  font-weight: 400;
  src: url(./assets/material_icons/material_icons.woff2) format('woff2');
}

.material-icons {
  font-family: 'Material Icons';
  font-weight: normal;
  font-style: normal;
  font-size: 24px;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-block;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  -webkit-font-feature-settings: 'liga';
  font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
}

.mat-radio-button{
  margin: 10px;
}

.mat-checkbox{
  margin-bottom: 10px;
}

.Done-numbers{
  color: red;
  font-weight: bold;
}

.finInfo-hint{
  color: gray;
}

.finInfo-success{
  color: green;
}

.Arabic {
  font-family: "AXtManal" !important;
  margin: 0;
  /* background: #fff; */
  font: normal 16px/20px Verdana;
  color: #1072BA;
  text-shadow: 0 0 0 #1072BA;
}

.English {
  font-family: "Rotis" !important;
  margin: 0;
  /* background: #fff; */
  font: normal 16px/20px Verdana;
  color: #1072BA;
  text-shadow: 0 0 0 #0078be;
}

Update 1:

Please check out this stackblitz example , the problem is very clear in it

1- I am expecting that the enclosing div with the Arabic class shall change the font & color of the contained material form fields but it doesn't (like the first field with Sushi, font is not changed)

This is very important as all elements are enclosed in a div with ngClass that have either English or Arabic & I want to apply the class to all enclosed elements including the material form fields

2- How to change the color of all the form labels from the blue to red or green ?

like image 940
Ahmed Elkoussy Avatar asked Jan 01 '23 21:01

Ahmed Elkoussy


1 Answers

Please check out this minimal example (I've had to adjust the font-family to make this example work).

You're overwriting some of your font style definitions. Either define your font-family, -size and -weight all separately like in the following adjusted .Arabic definition:

.Arabic {
  font-family: 'Shadows Into Light', cursive;
  margin: 0;
  /* background: #fff; */
  font-size: 16px/20px;
  font-weight: normal;
  color: red;
  text-shadow: 0 0 0 #1072BA;
}

Or set the font properties with the shorthand declaration like in this modified example:

.English{
  margin: 0;
  /* background: #fff; */
  font: normal 16px/20px 'Pacifico', cursive;
  color: green;
  text-shadow: 0 0 0 #0078be;
}

Edit

To answer to your comment / edited question:

I find the font in the computed values but it is striked through and not applied, it is only applied if I apply the class specifically on the mat-form field

You have to apply the class explicitly on .mat-form-field if you want to change it because within the prebuilt-themes/indigo-pink.css it's defined explicitly as

.mat-form-field{
    font-size:inherit;
    font-weight:400;
    line-height:1.125;
    font-family:Roboto, "Helvetica Neue",sans-serif
}

same for the label color.

With CSS you always have to be at least as specific as the already existing style definition.

You could do this:

.Arabic .mat-form-field,.mat-form-field-appearance-legacy .mat-form-field-label,
.mat-input-element,.mat-form-field.mat-focused .mat-form-field-label{
  font-family: 'Shadows Into Light', cursive;
  margin: 0;
  /* background: #fff; */
  font-size: 16px/20px;
  font-weight: normal;
  color: red;
  text-shadow: 0 0 0 #1072BA;
}
.Arabic .mat-form-field.mat-focused .mat-form-field-ripple{
  background-color: red
}

But that's not very nice I think. Better solution would be to create two custom themes, one for each language and set the colors and fonts there. This way your color and font definitions will apply to the nested elements automatically. This guide is a good read regarding custom themes.

EDIT 2: angular material theming

As mentioned in my previous edit, creating custom themes might be the better solution for your problem. Custom themes in angular material are quite powerful, however you need to set up quite a bit first. After that it's just a matter of a few lines to adjust the color, fonts etc.

I've created a new stackblitz where you can see the set up of a default and two custom themes and the adjustment of color and fonts of the material-form-field. I've commented every section but I'll briefly explain here as well:

The general structure of your styles.scss should be:

  • importing the required angular material mixins
  • defining the fonts
  • defining/importing custom component themes
  • defining a default theme
  • defining all other custom themes

After you've imported @import '~@angular/material/theming'; you can start adjusting the fonts (if you wish). To do so, you just need to define a new mat-typography-config e.g.:

$arabic-typography: mat-typography-config(
  $font-family: '"Shadows Into Light", cursive'
);

$english-typography: mat-typography-config(
  $font-family: '"Pacifico", cursive'
);

To apply those font-configs you need to and them over to the mat-core-mixin which takes care of the rest: @include mat-core($english-typography);. Now, if you only want to apply your font-config to a specific custom theme, you have to add your font-config within the theme definition.

A theme is defined by the following structure: define your desired main colors an the theme by using the mat-light-theme-mixin. To apply the theme, use @include angular-material-theme(<theme name>);

$app-primary: mat-palette($mat-indigo);
$app-accent:  mat-palette($mat-amber, A200, A100, A400);
$app-warn:    mat-palette($mat-red);
$app-theme:   mat-light-theme($app-primary, $app-accent, $app-warn);
@include angular-material-theme($app-theme); 

To achieve your multiple theme setup, you can wrap a theme definition within a CSS-class name like so:

.Arabic {
    $arabic-primary: mat-palette($mat-orange);
    $arabic-accent:  mat-palette($mat-blue, A200, A100, A400);
    $arabic-warn:    mat-palette($mat-red);
    $arabic-theme:   mat-light-theme($arabic-primary, $arabic-accent, $arabic-warn);
    @include mat-core($arabic-typography);
    @include angular-material-theme($arabic-theme);
}

Now, the .Arabic theme is only applied if your html elements is a descendant of an element with the .Arabic class. Additionally I've added @include mat-core($arabic-typography); which tells the theme engine to just apply the $arabic-typography to the $arabic-theme.

Final step to accomplish your styling is to define a custom component theme which styles the mat-form-fields as desired. This is now a matter of a few lines:

@mixin my-custom-component($theme) {
  // retrieve variables from current theme 
  $primary: map-get($theme, primary);

  // style element
  mat-form-field, .mat-form-field-appearance-legacy .mat-form-field-label {
    color: mat-color($primary);
  }
}

This custom component theme is then added to your custom themes by adding the line @include custom-components-theme(<theme name>); to each theme definition. (custom-components-theme is a little helper function. Read more about it in the stackblitz).

That's it. If you need to adjust more components, you just have to create a custom theme for that component and add it to the custom-components-theme mixin.

like image 95
coreuter Avatar answered Jan 04 '23 10:01

coreuter