Angular Material MatFormField appearance="fill" theming questions - css

I have a question dealing with Angular Material theming, specifically the MatFormField directive. Probably around Material v6, I found that the matFormField directive has new options such as appearance="fill" and appearance="outline", I have found the appearance="fill" useful, but I'd like to know how to change the background color, of the fill being used.
I have tried a few approaches such as,
<input class="w-100 bg-white form-control" #tileFilter
[formControl]="filterBy"
[matAutocomplete]="spiritilesAutocomplete"
[matChipInputFor]="chipList"
placeholder="Search by... Keyword, Author, Title, Story, etc."
>
I've also tried selecting
mat-form-field .mat-form-field-flex{
background-color: white;
}
and many other variations of selecting and styling mat-form-field in particular, but I cannot find the css selector nor, an api reference to the background color in the documentation. I see that Material allows theming of the underlined portion and the label, but I would like to target specifically the background-color. Could anyone please point me in the right direction.

In this case, use ng-deep in your component css file.
::ng-deep {
.mat-form-field .mat-form-field-flex{
background-color: white;
}
}

You need to add !important to the background-color value in order to make it work:
.mat-form-field-flex {
background-color: white !important;
}

you can try :
::ng-deep .mat-form-field-appearance-fill .mat-form-field-flex {
background-color: #fff;
}

Related

Can't remove the space where the Date-picker Label was supposed to be

I am trying to remove the extra space where the label was supposed to be (the green part)
This seems to be the CSS for the date-picker, now here comes the problem :
I added this in the .css file, but it doesn't seem to do anything.
.mat-form-field-appearance-fill .mat-form-field-flex {
padding-top: 0.0em !important;
padding-right: 0.0em !important;
padding-bottom: 0px !important;
padding-left: 0.0em !important;
}
Yes, the CSS file is linked to the html file, when I try to modify something else it works.
Any ideas why?
EDIT: I am using the Angular Material Date-picker
This is the HTML
<mat-form-field appearance="fill">
<mat-date-range-input [formGroup]="range" [rangePicker]="picker">
<input matStartDate formControlName="from" placeholder="From">
<input matEndDate formControlName="to" placeholder="To">
</mat-date-range-input>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-date-range-picker #picker></mat-date-range-picker>
<mat-error *ngIf="range.controls.from.hasError('matStartDateInvalid')">Invalid starting date!</mat-error>
<mat-error *ngIf="range.controls.to.hasError('matEndDateInvalid')">Invalid ending date!</mat-error>
</mat-form-field>
Your CSS rules are correct. You are most likely running into view encapsulation issues.
If you are using the CSS file defined by your styleUrls array in your component, your rules will not pierce through to the Angular component. You can get around this in two ways.
Move your rules to a top level css/scss file.
Use the ::ng-deep pseudo-class to apply the rule from your component. (I'd recommend nesting this in the :host pseudo-class to limit your scope).
:host ::ng-deep .your-class {
// rules
}
Here is a StackBlitz to show both these methods working: https://stackblitz.com/edit/angular-bvn3gy?file=src%2Fapp%2Fdate-range-picker-comparison-example.css

Why does changing css for a single component affect all other components?

Goal: Have CSS only affect the component its on, not others. I only wanted to affect my dropdown, not other text entry fields:
Background/Problem: I understand why it would affect multiple items on the same page (mat-form-field's). But don't understand why it would affect OTHER pages. I looked into it but still unsure.
What I tried:
For example, I originally had:
::ng-deep .mat-form-field-appearance-outline .mat-form-field-flex {
height: 40px !important
}
::ng-deep .mat-form-field-infix {
padding-top: 1px !important;
padding-bottom: 2px !important;
}
But it was affecting the spacing of all form-fields on the page, so I edited it to be:
::ng-deep .mat-form-field-appearance-outline .mat-form-field-flex {
height: 40px !important
}
::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix {
padding-top: 1px !important;
padding-bottom: 2px !important;
}
Other unchanged CSS:
.title-container {
position: relative;
margin-top: 8px;
}
.language-field {
position: absolute;
right: 0;
top: 0;
margin-top: -16px;
width: 115px;
height: 20px !important;
}
This fixed that, but it is still odd to me that changing something on login.component.css would affect all other pages in the site such as profile.component.css
Here is associated HTML for login.component:
<div class="title-container">
<mat-card-title class="text-center">
Please Sign In
</mat-card-title>
<form [formGroup]="_siteForm">
<mat-form-field class="language-field" appearance="outline">
<mat-select (selectionChange)="changeSite($event)" [value]="languages[i].value">
<mat-option *ngFor="let language of languages" [value]="language.value">
{{language.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>
</form>
</div>
When I researched into this:
I found some SO articles (such as Angular 2+ : Component style keeps affecting other components) mentioning using encapsulation: ViewEncapsulation
However, when looking through the site, I don't see this used anywhere, however there is css on different components that all mention mat-form-field but with different values. This seems like it would indicate that encapsulation is not needed.
In regular HTML I did not use to have these problems, but am confused on how this is working in Angular. Does this have something to do with Angular being a SPA?
I think it's your ::ng-deep, remove that.
Then use a specific class name and declare it in that components css file.
e.g. in home.component.css
.mat-form-field-flex {
height: 40px !important
}
It's slightly hard to grasp what you're trying to show here without a code snippet with that CSS.
But if it's breaking Angular's view encapsulation which all components have by default, I'd be almost positive it's because you're using !important selectors, these should really only be used in the rarest of situations - https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
The reason for this is because using !important will break the css specificity Angular uses to encapsulate it's components.
Css specificity works like so.
Inline styles are worth 1000pts
Id's are worth 100pts
Classes are worth 10pts
Elements are worth 1pt
The !important is essentially worth infinite points it always takes precedence.
div>p>.className = 12pts
div>p>#classname = 102pts
This means that any styles in
div>p>#classname
will take priority over any styles in
div>p>.classname
I won't go into details here about how Angular achieves there encapsulation with this technique, if your interested here's a good article - https://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html
Ensure you haven't set encapsulation to ViewEncapsulation.None
#Component({
selector: "my-component",
templateUrl: "./my-component.html",
styleUrls: ["./my-component.scss"],
encapsulation: ViewEncapsulation.None
})
I also got the same problem. You are using ::ng-deep. ::ng-deep is a global level element it affect all the component. So, use :host as prefix. :host will contain the ::ng-deep in the same component. It won't allow it to affect other components. Use this :host ::ng-deep. Replace all ::ng-deep with :host ::ng-deep.

Override primeng css classes in Angular

The thing is that I want to override the CSS classes of primeng and change some colors. No matter how I do it it doesn't change. If change the ViewEncapsulation to none the component doesn't even appear. I've tried something like this:
.ui-chkbox-box.ui-state-active, .ui-radiobutton-box.ui-state-active {
border: 1px solid red !important;
background: red !important;
color: #FFFFFF;
}
Trying to override the properties in the component css but it still doesn't work.
I know other people have asked the same question but none of the answers has helped me so I'm a little bit desperate.
Add ::ng-deep
::ng-deep .ui-chkbox-box.ui-state-active{...}
I added the classes to the app.less file and it worked like a charm. The component .css was not working.

Material Design Lite Styling Inputfields

I'm having some difficulties styling mdl-textfield.
Specifically, styling size and color the floating label, and height and color of the animation after pressing the input field.
Effectively, this is my starting point, as taken from the component list.
https://jsfiddle.net/2aznyc4n/1/
<form action="#">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="sample3" placeholder="Text here.">
<label class="mdl-textfield__label" for="sample3">Text...</label>
</div>
</form>
I am able to set the size and color of the floating label by adding into the label in the html
style="font-size:x-large; color:purple"
So is it some kind of bug that this has no effect when the label goes floating, if this is set in the css? If I set the style in the html and the css, then both of them suddenly has an effect. I just cant wrap my head around this.
If all possible, I want to avoid having styling in my html.
I have been digging through the source code, with no success in figuring out the styling of the mdl-js-textfield color and height.
Customization of MDL is a little bit tedious. At the beginning you can choose your primary and accent color and have a set of useful and beautiful componets, but when you need customize something a little bit, difficulties come out.
I digged for MDL source code in order to find what classes added color and font-size styling. I solved the need to adjust color and font-size of input text floating adding this hacking code in my css.
.mdl-textfield{ input[type="text"]{ font-size: 24px; color: #color500;} }
.mdl-textfield--floating-label.is-focused .mdl-textfield__label, .mdl-textfield--floating-label.is-dirty .mdl-textfield__label, .mdl-textfield--floating-label.has-placeholder .mdl-textfield__label{
font-size: 14px;
top: -5px; //Manages floating label fly
}
.mdl-textfield__label{ font-size: 24px; top: 20px; color: #color500;}
Normally the customization should be done with the custom CSS theme builde.
But if you prefer to use your own css you should use !important.
.mdl-textfield__input {
color: black !important;
}
For the pleaceholder text you need to use vendor prefix CSS:
::-moz-placeholder { /* Firefox 19+ */
color: red !important;
}
::-webkit-input-placeholder {
color: red;
}
I really struggled lots specifically with the bottom-border-color after the animation but thankfully after some research I could deduct a solution mentioned over here (it's prohibited to duplicate answers, so I rather put a direct link to it):
https://stackoverflow.com/a/43512625/1920145
Hope it helps many more people.

why does changing the `background-color` of a button change other styles too?

http://codepen.io/anon/pen/KwKOaz
Changing only the background-color significantly changes the style on a button element, specifically the border style.
This happens on chrome, safari, and firefox on a Mac. Why does this happen? How can I safely change its background color?
Browser vendors apply custom styling to UI elements like buttons and input fields. Altering one of these overwritten attributes results in disabling all of the other vendor styles on that element as well. If you want to change one attribute, you have to alter the others as well, I'm afraid.
Unfortunately I can't tell you why they do this - probably there is might be some spec behind, but I cannot find any evidence for that.
When all the styles are untouched, the browser uses the host OS's given API to render the given control. This will make the control look native to the platform, but if you apply any style to that control/element, the browser cannot guarantee that the given style can be applied in the given platform, so it defaults back to a simplified, fully css solution.
Also note, that styling control elements, though works, not covered by stable standards yet.
For example, the NSButton (native control behind the button in OS X) doesn't have an option to set the background color, so the browser faces an impossible task. On Windows, you can change the background color, this is why people report not seeing your issue on Windows.
Sometimes CSS styles are inherited. However, you are applying styles to your body which is everything in HTML. Personally I don't apply anything to body other than maybe reset or normalize CSS. That said, you can use CSS selector operators and\or id/classes to minimize:
http://www.w3schools.com/cssref/css_selectors.asp
Example:
html
btw don't write html like this just easier to read
<body>
<div class="wrapper">
<button class="all-btns red">
Cancel
</button>
<button class="all-btns green">
Save
</button>
</div>
</body>
css
.div.wrapper {
width: 100%;
height: auto;
background: #efefef;
}
.all-btns {
border: solid 1px #000;
width: 50px;
line-height: 48px;
height 35px;
color: #fff;
}
.btn.red {
color: #fff;
background: red;
}
.btn.green {
background: green;
}

Resources