How to get global selector inside emulated view encapsulation (CSS / Angular2) - css

I have a Home component with this inside:
<alert type="info">Hello from ng2-bootstrap</alert>
Inside my home.style.scss, I have this:
:host .alert {
background-color: green;
}
which should change the background color to green, but it does not.
The above css code will produce this style:
[_nghost-wjn-3] .alert[_ngcontent-wjn-3] {
background-color: green;
}
and the final HTML looks like this:
<home _nghost-wjn-3="">
<div _ngcontent-wjn-3="" class="card-container">
<alert _ngcontent-wjn-3="" type="info" ng-reflect-type="info">
<div class="alert alert-info" role="alert" ng-reflect-initial-classes="alert" ng-reflect-ng-class="alert-info">
Hello from ng2-bootstrap Sat Sep 17 2016
</div>
</alert>
</div>
</home>
I don't know what the problem is here, but I think the selector is wrong. I'd like the final selector to be:
[_nghost-wjn-3] .alert
instead of:
[_nghost-wjn-3] .alert[_ngcontent-wjn-3]
Or in other words, why is there no _ngcontent-wjn-3 attribute on <div class="alert">...</div>?
Maybe I'm doing the whole thing wrong. What I'm trying to achieve is to customize the CSS of the individual bootstrap components (<alert> in the code above) as provided by the ng2-bootrap library (https://github.com/valor-software/ng2-bootstrap) inside my custom components (<home> in the code above).
I'm using the default view encapsulation (emulated) in the home component.
How can I do that please?

I figured it out myself. This is what I was looking for:
:host /deep/ .alert {
background-color: green;
}
The above code will produce the following:
[_nghost-wjn-3] .alert {
background-color: green;
}
This way I can modify the default styles of a bootstrap class (.alert, in this case) inside of my component <home>.
Source: https://angular.io/docs/ts/latest/guide/component-styles.html

You need:
[_nghost-wjn-3] alert[_ngcontent-wjn-3]
Instead of:
[_nghost-wjn-3] .alert[_ngcontent-wjn-3]
If you go and check your structure, alert tag has the ngcontent... attribute, not his div child with alert class.

Related

How styling works over components in angular?

Question is not clear but I'll break it down. In angular we can write isolated css for styling. It works pretty well for native html elements. But unlike react, angular wrap our html with custom elements like <app-card>...</app-card>. When I write css for those wrapper elements, it doesn't work .
If I have a post list like
<div class="post-list">
<app-card [post]="post" *ngFor="let post of posts"></app-card>
</div>
If I write css to apply some vertical gap between app-card components in PostListComponent. Well nothing happens.
.post-list app-card:not(:last-child) {
margin-bottom: 2rem;
}
How can I make it work? Or with angular logic, how can I apply vertical gap between angular components
Just add display: block; on your app-card component & it will work as expected.
.post-list app-card {
display: block;
}
.post-list app-card:not(:last-child) {
margin-bottom: 2rem;
}
<div class="post-list">
<app-card>Card 1</app-card>
<app-card>Card 2</app-card>
<app-card>Card 3</app-card>
</div>
You can define encapsulation: ViewEncapsulation.None in your Component like this:
#Component({
selector: 'foo',
template: './foo.component.html',
styleUrls: ['./foo.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class FooComponent { }
Which will treat your .css as the same if you were putting it in the global scope.
To be more accurate, it won't append .fooComponent to each css rule in foo.component.scss.
You can make the iteration in div tag then add your class
<div class="post-list">
<div class="post" *ngFor="let post of posts">
<app-card [post]="post"></app-card>
</div>
</div>
And in your css
.post-list .post:not(:last-child) {
margin-bottom: 2rem;
}
There is no reason it shouldn't work. Just tried to put in some of your code here. https://stackblitz.com/edit/angular-scss-demo-icqrye
app.component.html
<div class="post-list">
<app-new *ngFor="let item of [1,2,3,4]"></app-new>
</div>
styles.scss
.post-list app-new:not(:last-child) p {
margin-top: 2rem;
color: green;
}
And it works perfectly. Are you looking for something else?
And if you want to add the style (margins) to the component directly, you will first need to set the display of the component to block/flex as per requirement.
.post-list app-new:not(:last-child) {
display: flex;
}

Primeng's [styleClass] with conditional styling

I'd like to put a conditional styling on a primeng 'p-overlayPanel' element. I have tried:
<p-overlayPanel [styleClass]="#{(bean.comment) ? 'style1' : 'style2'}">, but it's not working.
[ng-class]="bean.comment ? 'style1' : 'style2'" - this is not working either.
Styleclass works only without a condition like so:
<p-overlayPanel [styleClass]="style1"> // html file
p-overlayPanel .style1.ui-overlay { background-color: yellow; } // css file
While [ng-class] doesn't work at all (but works fine on vanilla JS elements). Have I missed something? My questions are following:
Is 'ng-class' not working for some of the elements from ngPrime collection?
How to correctly conditionally apply 'styleClass' for p-overlayPanel element?
I'm using Angular 8.
styleClass accept string as a css class or list of classes and apply to the elemnt at that already have a list of these classes overlaypanel ui-widget ui-widget-content ui-corner-all ui-shadow
so if you want to change the background color you have to do it like this
.style1.ui-overlaypanel{
background-color: red;
}
.style2.ui-overlaypanel{
background-color: green;
}
you have to add the class to the global style file not the component style file and if you use style property the value will pass to ngStyle directive.
demo 🚀
🦑 overlaypanel.ts
Updated 🌟
you can use ngClass but the style must be change like the example below , because now the css classes will apply to the element directly.
.style1 .ui-overlaypanel{
background-color: red;
}
.style2 .ui-overlaypanel{
background-color: green;
}
demo 🥈
You can use [ngClass] like this:
<input pInputText [ngModel]="vendor.iban" name="pIban" #pIban="ngModel" (click)="some(pIban)" class="col-md-7 ui-inputtext ui-widget ui-state-default ui-corner-all " [ngClass]="{'errorVendor': vendor.iban=='' && pIban.touched}" />

styling react-select using classes

I am using react-select in my code. https://www.npmjs.com/package/react-select
I want to style my drop down using classNames, so that I referred https://react-select.com/styles. The DOM structure of react slect is shown in the link.
How can I style the react-select using classNames?
Can anyone show a sample code?
According to the documentation
If you provide the className prop to react-select, the SelectContainer
will be given a className based on the provided value.
So it should work like this:
<Select className="abc" .... />
Then you can use your classname as usual.
.abc {
color: red;
}
You can also use classNamePrefix
by specifing a classNamePrefix, react-select will render all classNames with your prefix. If you use this:
<Select className="abc" classNamePrefix="react-select" ... />
Your Select will automatically render a class structure like this:
See their example:
For example, given className='react-select-container' and classNamePrefix="react-select", the DOM structure is similar to this:
<div class="react-select-container">
<div class="react-select__control">
<div class="react-select__value-container">...</div>
<div class="react-select__indicators">...</div>
</div>
<div class="react-select__menu">
<div class="react-select__menu-list">
<div class="react-select__option">...</div>
</div>
</div>
</div>
So in your css, simply do:
.react-select-container {
background-color: 'red';
}
.react-select__menu {
height: 100vh;
}
etc

How to use component variable within css / style tag in Angular 2?

How can I use component variables within style TAG in Angular 2?
I do have an Angular 2 component for my header which I like to color depending on a users setting. Thus I'd like to assign an background and font color. While I know how to to this with an attribute binding to an element, I couldn't figure out how to use in a style tag.
Using attribute binding for style works well, however this gets pretty anoying for several subelements, especially if they are nested within other sub components. [ngStyle]= attribute is also only working on a single element.
<header id="header" [style.background-color]="changeBackground()">
<div>
Some Text
Some Link
<subcomponent></subcomponent>
</div>
<div> ... a lot mor stuff </div>
</header>
Thus I'd like to add something like
<style>
#header, #header a {
color: {{mycolor}};
}
</style>
to the html template. However this is not working
Similar Questions do not answer this question yet and only show attribute binding as a solution:
Angular2 dynamic change CSS property
Dynamically updating css in Angular 2
https://scotch.io/tutorials/all-the-ways-to-add-css-to-angular-2-components
https://coryrylan.com/blog/introduction-to-angular-2-ngclass-and-ngstyle
It looks to me like you are just creating a new component called 'subcomponent', why not do that?
subcomponent.ts:
import { Component } from '#angular/core';
#Component({
selector: 'subcomponent',
templateUrl: './subcomponent.html',
})
export class SubComponent {
mycolor = 'blue';
}
subcomponent.html:
<style>
#header, #header a {
color: {{mycolor}};
}
</style>
To your #Component object, add
styles:[ `#header, #header a {
color: {{mycolor}};
}`]
So for example:
#Component({
template: `<header id="header" [style.background-color]="changeBackground()">
<div>
Some Text
Some Link
<subcomponent></subcomponent>
</div>
<div> ... a lot mor stuff </div>
</header>`,
styles: [ `#header, #header a {
color: {{mycolor}};
}`
`]
})
Use NgStyle as explained in this answer
https://stackoverflow.com/a/41903349
in short
<header id="header" [ngStyle]="getStyle()">
<div>
Some Text
Some Link
<subcomponent></subcomponent>
</div>
<div> ... a lot mor stuff </div>
</header>
and
getStyle(): any {
return {"background-color" : this.changeBackgroundColor()};
}

How can I change the colour of an ionic item-divider when it is clicked from the default

I have a ng-click assigned to an ionic item-divider as follows:
<div class="item item-divider" ng-click="toggleShowingProfile()">
PROFILE
</div>
When this gets clicked it goes grey momentarily. I would like a much more subtle effect. I want it to go slightly lighter in colour so am trying to change the opacity like this:
.item-divider{
background-color: #336688;
color: white;
}
.item-divider:active{
opacity: 0.8;
}
My CSS code seems to make no difference. Is there a way to override the default behaviour?
CSS Only
The easiest way to override it is to give it a custom class and use that as your CSS selector. Also, the item is getting the activated class added to it on click, so :active won't change anything. To override you need to do something like this:
HTML:
<div class="item item-divider custom-item-divider" ng-click="toggleShowingProfile()">
PROFILE
</div>
CSS:
.custom-item-divider.item-divider {
background-color: #336688;
color: white;
}
.custom-item-divider.item.activated {
background-color: #336688;
opacity: 0.8;
}
Codepen demo: http://codepen.io/brandyshea/pen/epEedW
Note: you could also use <ion-item> instead of using a <div> with the item class.
Sass
If you are using Sass, you can override the Sass variables directly:
$item-divider-bg
$item-divider-color
$item-default-active-bg
$item-default-active-border
See these variables here: https://github.com/driftyco/ionic/blob/master/scss/_variables.scss#L311
and here:
https://github.com/driftyco/ionic/blob/master/scss/_variables.scss#L372
You will want to override the variables in your own Sass file, not Ionic's Sass files directly.
Let me know if you have any questions!
<div class="item item-divider" ng-click="toggleShowingProfile()">
PROFILE
</div>

Resources