Angular Material: Styling mat-form-field inside mat-toolbar - html

I'm trying to create a toolbar using Material's mat-toolbar with an input and select inside of it. For both, I am using Material's provided components (mat-input and mat-select respectively) inside of mat-form-fields as advised. My code looks like this:
<mat-toolbar>
<mat-form-field appearance="outline">
<mat-icon matPrefix>search</mat-icon>
<input type="search" matInput placeholder="Search" />
</mat-form-field>
<mat-form-field appearance="outline">
<mat-select [(value)]="omitted">
<mat-option *ngFor="let omitted of omitted" [value]="omitted.slug">
{{ omitted.name }}
</mat-option>
</mat-select>
</mat-form-field>
</mat-toolbar>
At the moment, the input and select are too tall to completely fit in the toolbar. I am trying to style them to make them fit (by reducing height, padding, margin, etc.). However, Angular adds elements between mat-form-field and the contained elements. I am unable to style those elements from the component's Sass because of view encapsulation. So, even if I style everything immediately present in my template, the generated elements have heights, margins, and paddings that force the observed element to be outside of the toolbar.
I don't want to include a global style for those components because I don't want other mat-form-fields to get affected.
Turning off view encapsulation would essentially be the same thing as using global styling.
::ng-deep is deprecated so I can't use that.
I could style my own input and select from scratch, but then I lose out on the prebuilt styling that Material provides. Is there any way that I can style these Material components to fit in my toolbar?

I had similiar problem and I have solved it with wrapping component with a div and then style it in global stylesheet with this
.filters {
mat-form-field {
div.mat-form-field-flex {
align-items: flex-end;
}
div.mat-form-field-prefix {
padding-right: 12px !important;
}
}
}
In your case, you could add class (or id) to the toolbar or wrap the form field with a div and in order to encapsulate the rules you want.

You can set the encapsulation: ViewEncapsulation.None, in the #Component decorator.
This will free the component from the restrains about styling. Keep in mind if you are using global styles you have to take care of the proper styling I will suggest using BEM for naming the CSS styles and not using generic naming.
More info - https://angular.io/api/core/ViewEncapsulation

I added the following rules in my global stylesheet to make the mat-form-field fit:
[the selector for the mat-form-field I wanted to affect]
.mat-form-field-flex, .mat-form-field-label-wrapper
padding-top: 0
.mat-form-field-wrapper
padding-bottom: 0
.mat-form-field-underline
bottom: 0
.mat-form-field-infix
border-top: 0

You can add subscriptSizing="dynamic" to mat-form-field. This will not reserve spacing for the subscript below the mat-form-field.

Related

how to override angular material mat-option style

The height doesn't get bigger and the inscription gets smeared and not pretty
I have already tried many types of solutions but none of them worked I tried to do
::ng deep .mat-option{...}
But it didn't work
I tried to do
::ng-deep cdk-global-overlay-wrapper{
But that didn't work either
And I want to increase the height of
mat-option and it doesn't work
Assign a panel class for the mat-select, so that a custom class is available inside the overlay,
<mat-select panelClass="custom-select">
<mat-option>option1</mat-option>
<mat-option>option2</mat-option>
</mat-select>
then in the main styles file styles.css add css rules in the custom class to override the default styles
.mat-select-panel.custom-select .mat-option{
height: 50px;
}

Material ui checkbox css is overriding across the components in angular

I'm trying to override material UI checkbox css in my Home Component and it is working fine. But there are side effects like css of checkbox in form component is overriding. Can anyone suggest a solution for this.
HTML used
<mat-checkbox formControlName="home">
Home
</mat-checkbox>
css used for over riding by default it is grey color
::ng-deep .mat-checkbox .mat-checkbox-frame {
border-color: blue !important;
}
Form component mat checkbox - for this component also it is overriding border color to blue without writing any css
<mat-checkbox formControlName="form">
Form
</mat-checkbox>
I believe this is happening due to usage of ::ng-deep
I even tried ViewEncapsulation also in the Home component. It is still overriding css in Form component and other css in both the components.
Any help regarding this would be appreciated.
To apply the style only inside a specific child component, add the :host selector to the following code in the CSS of that component:
:host ::ng-deep .mat-checkbox .mat-checkbox-frame {
border-color: blue !important;
}
This will scope this rule to all checkboxes which are in this current component and all its children and will work pretty well in case of routed components.
But if you want to stick this css rule only for home page template then you can use:
home.component.css
.mat-checkbox ::ng-deep .mat-checkbox-frame {
border-color: blue !important;
}
Angular will replace it with:
.mat-checkbox[_ngcontent-rvb-c0] .mat-checkbox-frame {
border-color: blue !important;
}
where _ngcontent-rvb-c0 is unique identifier of current compoent

Use pseudo selectors in Angular Component?

I created a component with a template containing a div holding the "input"-value and an indicator showing if capslock is active. When I add the Bootstrap .form-control class to the host element, it looks pretty much like other input fields except when being focused or disabled.
Is there a way to make use of :disabled and other pseudo selectors like :focus defined in Selectors 3 when creating Angular Components?
I'm stuck with finding a good way to create form components that shares the look and feel of other input components.
Are there other (preferred) ways to make use of input stylings without having to redefine everything?
Would it be better to create a directive and "hack" the template using Renderer2?
Not sure if that's what you are looking for, but having a template like
<div class="form-control">
<input type="password" class="custom-input">
</div>
try targeting your input with a css class and style it (if you are using scss) with e.g.
.custom-input {
//some styles
&:disabled {
color: grey;
background: lightgrey;
}
}
If you are using regular css you could do something like
.custom-input:disabled {
color: grey;
background: lightgrey;
}

Delete border of mat-form-field with input (also for hover and focus)

I'm having a hard time styling my mat-form-field.
What I want is to delete the border from the field, also when the field is focused and the user is on hover. Right now I have this:
and I need to delete that border outside of my input. This is my form field:
<mat-form-field class="search-field" appearance="outline">
<mat-label>Search</mat-label>
<input matInput type="text" >
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
and in .scss:
mat-form-field.search-field {
.mat-form-field-flex {
background-color: white;
border-radius: 2rem;
color: transparent;
.mat-form-field-appearance-outline.mat-focused .mat-form-field-outline-thick {
border-style: none;
}
}
}
The "first" style is correctly applied, but not the style for the border.
Also I'm not totally sure this is the best way to stile it, but in the docs there is no indication on how to change all these parts.
Many of the Material styles are enforced with the !important flag. You can either try to overwrite them using !important in your code, which I wouldn't recommend, since it may not even work. You could try using ::ng-deep, tho. Material elements are not really str8 forward for modification, so either way, you'll have to 'hack' into it. Good luck :)

Angular 2 Material Customize md-menu

I am new to Angular 2 Material and I am trying to customize the style of the md-menu component.
<md-icon class="material-icons" [mdMenuTriggerFor]="menu">dehaze</md-icon>
<md-menu #menu="mdMenu" [overlapTrigger]="false">
<button md-menu-item>Item 1</button>
<button md-menu-item>Item 2</button>
</md-menu>
The predefined style settings work fine (e.g. setting the Menu to non-overlapping), but I would like to set the md-menu to 100% width and have a little space between the md-icon button, that expands the menu, which I can not do with the predefined directives from Angular 2 Material.
So far I found a solution with the /deep/ css command, but I read that the command is not supported by the major browsers any more.
What is a good way to customize a Angular 2 Material component? How could I style my md-menu, so that it has 100% width and some space between it´s expanding button?
To illustrate what I am talking about:
Draft of the menu
You can pass custom classes to menus.
<md-menu #menu="mdMenu" [overlapTrigger]="false" class="my-full-width-menu">
Then you can target that class with global styles.
For your needs, unfortunately, you'll need to know some information about where your menu overlay is positioned, and hardcode some repositioning
.mat-menu-panel.my-full-width-menu {
max-width: none;
width: 100vw;
margin-left: -8px;
margin-top: 24px;
}
Plunker Demo
The right way to do this is to create a custom overlay component with material's OverlayModule (current in the material package, but soon to be moved to the cdk).
In Angular, ViewEncapsulation.Emulated is the default option which means, it tries to narrow-down the scope of the affect by adding surrogate keys to the host-element etc. One option could be is to add below css. But mind, this ng-deep will also be deprecated soon. Have to wait to know the alternative! https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep
::ng-deep .mat-menu-panel {
max-width: none!important;
min-width: 400px!important;
}
To style mat-menu without turning off encapsulation for this component you should use 2 classes to increase specificity as exactly as you already did or use !important. However, to make it work you should put them into your global stylesheet so that you will override the default styles.