Values css _nghost-c0 in angular - css

I'm learning Angular 5 and I see the html tags with the ng generated attributes: _nghost-c0, _nghost-c1...
What does it mean?
[_nghost-c3] .employees[_ngcontent-c3] button[_ngcontent-c3] {
color: #681f32;
}

This is called Emulated Shadow DOM. These are attributes that angular uses to isolate component styles from one another.
To explain, let app.component.html like this
<header>
<span>from App Component</span>
</header>
<app-alert></app-alert>
app.component.css
header span {
color: red;
}
In alert.component.html
<header>
<span>from alert component</span>
</header>
alert.component.css
header span {
color: blue;
}
for more: https://dev.to/themeticulist/everything-you-should-know-about-styles-in-angular-12ab

Related

why moving class to shared css file in Angular increases bundle size

This is for an Angular 11 application. I have a shared css file I'm including in several components as follows:
#Component({
selector: 'app-my-x-selector',
templateUrl: './my-component-x.html',
styleUrls: ['component-x.css', 'shared.css']
})
Adding the following test class to one of the components' css file increases
the bundle size by by 61 bytes, which matches the size of the added source snippet. But moving the class to the shared css increases the bundle size by 140 bytes. Why? It seems like Angular effectively clones the class for each component that includes the shared css file which imho severly limits, if not defeats the purpose of having shared css.
.tr-test00 {
display: block;
margin-left: 45rem;
padding-left: 3rem;
}
#Ya, Imagine you has simple two components with a .css like
//component-one
template: `<h1>Hello</h1>`,
styles: [`h1 { color:blue }`]
//component-two
template: `<h1>By</h1>`,
styles: [`h1 { color:red }`]
Angular make an unique bundle similar to
h1[_ngcontent-edf-c40] {
color: green;
}
h1[_ngcontent-edf-c41] {
color: red;
}
And create an .html like
<hello _ngcontent-bwn-c39="">
<h1 _ngcontent-edf-c40="">Hello</h1> //<--this is the component one
</hello>
<other_ngcontent-bwn-c42="">
<h1 _ngcontent-edf-c41="">By</h1> //<--this is the component two
</other>
This makes that in component-one you see the h1 green and in component-two h1 red
When you refered a common .css to two differents components, Angular makes a bundle like
h1[_ngcontent-edf-c40] {
color: green;
}
h1[_ngcontent-edf-c41] {
color: green;
}
And again the .html is
<hello _ngcontent-bwn-c39>
<h1 _ngcontent-edf-c40>Hello</h1> //<--this is the component one
</hello>
<other _ngcontent-bwn-c48>
<h1 _ngcontent-edf-c41>By</h1> //<--this is the component two
</other>
This is the reason because the bunlde increase two times. If you want, you can take another aproach that is use a common .css and add in your angular.json in the way
.common h1{
color:green
}
And enclosed yours component in a div
<div class="common">
<h1>Hello</h1>
</div>
<div class="common">
<h1>By</h1>
</div>
The .html it's looks like
<hello _ngcontent-jxl-c46="">
<div class="common">
<h1>Hello</h1>
</div>
</hello>
<other _ngcontent-jxl-c46="">
<div class="common">
<h1>By</h1>
</div>
</other>

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;
}

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 to get global selector inside emulated view encapsulation (CSS / Angular2)

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.

How to style one react component inside another?

I'm new to css and I can't figure out how to position one component inside another in React. I can show them separately, but when I put one inside another. I don't see the one inside. I think the problem is in the css file
#homePage{
section{
h1{
text-align: left; //this is shown
}
//here I want to add the other React component but I don't know how
}
}
And the render method:
<div id="homePage">
<Component1>
<section>
<h1>Hi</h1>
<Component2>
</Component2>
</section>
</Component1>
</div>
Thanks.
From what i understand , you could have the className attribute defined inside your Component2's HTML tags.
class Component2 extends Component{
render(){
return(
<section className="component2styles">
This is Component2
</section >
);
} }
Now , you can change ur style sheet as
#homePage{
section{
h1{
text-align: left; //this is shown
}
//components2 style will be nested here
section.component2styles{
border:1px solid blue;
}
}
}
Or as an alternative you can try inline-styles , seems to be gaining a lot of traction in React development.
render(){
var styleobj={color:'red'};
return( <section style={styleobj} > This is Component 2 </section> )
}
Did you add some class/id to your Component2 like <Component2 className="my-specific-class" /> to style it?
(btw, I hope your css is less/sass one to allow nested styles like you did)
EDIT
By adding className attr. to your Component2, I mean adding it in Component2 render method like
render: function() {
return (
<div id="your-id" className="your-class">
some html here
</div>
);
}

Resources