Angular 2 no unique component identifier generated for select arrow div - css

I'm trying to remove the arrow from an angular material select component.
To do that I have a custom CSS file where I say display: none.
Here is the code:
https://stackblitz.com/edit/angular2-remove-select-arrow
but as my CSS is custom for this component, I saw there's no unique identifier generated for the arrow div so CSS is not applied.
Can you please let me know what would be the best way to do achieve that?
Thanks for your help.
Mike

When you state the styles in a component's CSS file, custom attributes are added to it automatically, so that CSS is not applied outside of the current component. But that causes issues when you want to apply CSS to other components, in this case, mat-select.
There are two ways to solve this issue
Set encapsulation to none in component
#Component({
selector: 'select-form-example',
templateUrl: 'select-form-example.html',
styleUrls: ['select-form-example.css'],
encapsulation: ViewEncapsulation.None,
})
export class SelectFormExample {
}
Add the custom styles in style.css file instead of the component's CSS file
select-form-example.css
I have updated the stackblitz with 1st step

Use ::ng-deep in your case but note that this one is already deprecated.
Now your css rule becomes like this: ::ng-deep .staffing-cell .mat-select-arrow-wrapper
Deprecation info: https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep
Now for the "appropriate" way you need to leverage the material theming in which you can look up in their docs: https://material.angular.io/guide/theming

Related

Make Angular component stylesheet work with sub-components

I'm relatively new to Angular, and I have a doubt about component stylesheets.
I have an Angular 12 app and created a component named my-component. The template of the component in question is something like this:
my-component.html
<div>
...some html...
<some-other-angular-component></some-other-angular-component>
...some other html...
</div>
some-other-angular-component is another component, either from the app itself or a third party library.
Now, what I want to do in my-component is apply some CSS rules to the contents of some-other-angular-component. I know that the HTML it generates contains classes that I can target, so I tried to add this to my component CSS:
my-component.scss
.some-other-angular-component-inner-class {
background-color: red;
}
However, this doesn't work, it appears that the component's CSS file only applies rules to the HTML defined directly in the component's template, not the HTML generated by sub-components.
Is there a way to make this work? I find myself having to add my CSS to the webapp's main style.scss file, even when I want to apply the rule only to the particular some-other-angular-component instance inside of my-component. It makes styling confusing and needlessly fragmented. Is this intended, or what am I missing?
I think you may want to look into View Encapsulation.
#Component({
selector: 'app-no-encapsulation',
template: `
<h2>None</h2>
<div class="none-message">No encapsulation</div>
`,
styles: ['h2, .none-message { color: red; }'],
encapsulation: ViewEncapsulation.None,
})
export class NoEncapsulationComponent { }
These styles will be added to head and will be applicable to other components as well if style rule matches.
Please note, with this you are only enabling this behaviour for just this component. Chances of overlapping CSS rules is still there but is lot less in comparison to directly putting styles in style.css.
I will also suggest that you add .class or #id attribute in mark up to ensure that your rules don't overlap by default.
For example:
.my-component .rule-one {
}
It will ensure that my rules are only applied are on component that has this class applied on it.

PrimeNg p-inputnumber cannot be styled

I am getting stuck trying to implement the PrimeNg Inputnumber element: https://www.primefaces.org/primeng/showcase/#/inputnumber
As per its documentation, there are a couple of attributes that can be used to style the input element, most notably styleClass and inputStyleClass. Unfortunately, neither of them work but rather they get completely ignored.
component.html:
<p-inputNumber
inputStyleClass="form-control-inputnumber" [(ngModel)]="subwinFld.orderAdd.doubleVal">
</p-inputNumber>
Global styles.css
.form-control-inputnumber {
background:red;
width: 100%;
}
I have used and successfully styled other primeNg elements before, using the exact same strategy, for example the p-calendar element. However, here it completely ignores the attribute.
What am I doing wrong?
Try to add :host ::ng-deep
Style are scoped, and there are not inherited by nesting.
:host ::ng-deep .form-control-inputnumber {
background:red;
width: 100%;
}
styleClass is the property that put the class on the first level of a PrimeNG Component.
inputStyleClass is the property that will put the class on the input itself for this specific component.
I often have to play with the style encapsulation with styleClass, so I believe it is the same for inputStyleClass
Word about ::ng-deep deprecation
Yes, for sure it is deprecated. To be totally fair, there is an alternative. But the alternative counterpart is huge and in my opinion, the big picture is worst.
You can make it work by changing your ViewEncapsulation in your component with :
encapsulation: ViewEncapsulation.None
as follow
#Component({
selector: '',
template: '',
styles: [''],
encapsulation: ViewEncapsulation.None // Use to disable CSS Encapsulation for this component
})
Reference 1 about alternatives and reasons of deprecation
Reference 2 about alternatives of ::ng-deep
The choice is yours, but for my part I continue to use this methodology with third party library like primeNG, because there is no real alternative.
You either choose to make your style global or your style scoped.
Kill the encapsulation for the sake of a third party library usage, seems to me an overkill process.
By making your ViewEncapsulation to none, you give up on style encapsulation, so beware of it.
HTML:
<p-inputNumber styleClass="input-styling"></p-inputNumber>
CSS:
::ng-deep .input-styling input {
width: 20px !important;
}
The cause for the missing styling was a runtime error in the typescript of the component, that prevented the correct compilation of the DOM.
I assumed that did not matter, since they should not be related at all, but they are (somehow). Since others may have the same erroneous assumption, I am leaving this question here, rather than deleting it.
Simply add
styleClass="w-full" to p-inputNumber tag to adjust 100% width or according style to reach desired width in reference to https://www.primefaces.org/primeflex/width
No encapsulation: ViewEncapsulation.None is needed and no extra css classes/styling is required.

How can I override twitter-bootstrap on one of the component in Angular 4

I am very new at Angular 4. Apologize for my very basic question.
What I am trying to do, is changing the background color of body element of a particular component.
in the component declaration Material View I have the following:
#Component({
selector: 'app-material-view',
templateUrl: './material-view.component.html',
styleUrls: ['./material-view.component.css'],
providers: [GetDataService]
})
and in the material-view.component.css file I put the following line:
body{
background-color: cadetblue !important;
}
The problem is the background color is not changed.
When I inspect the element in the chrome debugger tool, I see that the css is overwritten by tweeter bootstrap. I would expect the css in the component declaration is the most immediate css to be applied to that component. But it seems that I was wrong.
I am not sure why.
Any hint on that is very much appreciated.

How to Style ng-bootstrap - Alternative to /deep/

I am using the accordion component from ng-bootstrap in one of my apps and the /deep/ (aka: ::ng-deep and >>>) selector to set its styles. However I saw this selector has been deprecated.
Is there an alternative to set the styles of the ng-bootstrap components?
Support for the emulated /deep/ CSS Selector (the Shadow-Piercing
descendant combinator aka >>>) has been deprecated to match browser
implementations and Chrome’s intent to remove. ::ng-deep has been
added to provide a temporary workaround for developers currently using
this feature.
From here: http://angularjs.blogspot.com/2017/07/angular-43-now-available.html
I've done some digging and it is possible to overwrite the ng-bootstrap styles if you turn off the view encapsulation for a component, like so:
#Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ExampleComponent {
constructor(public activeModal: NgbActiveModal) { }
}
For example, here I am customizing the styles for a modal dialog, because I assumed that my example component should be shown as a modal dialog and I want its width to be at maximum 70% of the view port in small screen sizes:
.modal-dialog {
#include media-breakpoint-down(xs) {
max-width: 70vw;
margin: 10px auto;
}
}
Please note that turning off the view encapsulation means that the styles for this particular component will be available throughout the application, therefore other components will have access to them and will eventually use them if you are not careful.
You have to make custom styling to override the default bootstrap variable in scss.
You can find all possible variables here ../node_modules/bootstrap/scss/_variables.scss
Bootstrap also provide a custom file for us add our styling ../node_modules/bootstrap/scss/_custom.scss
for eg: here i am overriding two variable that effect my accordion (i changed some random colors)
$link-color:$brand-warning;
$card-bg:$green;
and dont forget to remove !default in _custom.scss and you done with the custom styling.
Now need to build the css from scss
First install npm install -g grunt-cli globally
then navigate to \my-app\node_modules\bootstrap> npm install, this will install all dependencies.
Lastly run \my-app\node_modules\bootstrap> grunt, this will creates the css file.
This should work hopefully.
In my case "bootstrap.min.css" was not generated correctly, so now iam using "../node_modules/bootstrap/dist/css/bootstrap.css " in my .angular-cli.json file.

Angular 2 css modules

I tried use
#Component({
selector: 'about',
template: './about.hmtl',
styles: ['.block {background-color: red} ...'] // <-- This will generate css modules
})
This works fine, angular expands every class with attribute selector and give every DOM element unique attribute. But will application load fast when will be a lot of css modules(for example 20 components and about 100 lines CSS code for every component)?
When it comes to component css you don't want to have any duplication, it duplication and its a pain to maintain. Would recommend that you find the top most component or the parent component that contains all the child component you want to style and define your styles one. Use an external file or define them inline its up to you. Then within the component decorator set the encapsulation property to ViewEncapsulation.None that will mean that all the child component will inherit the parent components styles and you can maintain one bit of css rather than having it all over the place.

Resources