Angular 2 #Component Styles - css

How can I use Angular 2 styles in #Component with multiple classes on the same tag?
#Component({
styles: `.class1 .class2{background-color:red;}`
})
This generates the following css code:
.class1[<RANDOM_ANGULAR_ATTR>] .class2[<RANDOM_ANGULAR_ATTR>]{
background-color: red;
}
This will not select a tag defined like this:
<div class=".class1 .class2" RANDOM_ANGULAR_ATTR></div>
Is there any way to make this approach work?

Your styles should have the classes without a space between them. Multiple classes in the same selector must be written directly after each another – with no white space. For example:
.class1.class2 { background-color:red; }
And in order to select your object you should have the classes added like this:
<div class="class1 class2">Test css</div>
See the code below:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
styles: [
`
.class1.class2{background-color:red};
` ],
template: `
<h1>My First Angular 2 App</h1>
<div class="class1 class2">Test css</div>
`
})
export class AppComponent { }
For more options see also the following blog posts (about Shadow DOM, Encapsulation Types .. any other cool things):
https://scotch.io/tutorials/all-the-ways-to-add-css-to-angular-2-components
http://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html

Have you looked at Justin Schwartzenberger's NG-Conf talk on CSS styles and the randomly generated tag? https://www.youtube.com/watch?list=PLOETEcp3DkCq788xapkP_OU-78jhTf68j&v=J5Bvy4KhIs0
potential options are to:
Use a styleUrls template
change encapsulation
use a different class (since its only relevant to this component its ok to name something simple vs using 2)

Related

Angular Material matTooltip break line elements

Im using Angular 7 and Angular material matTooltip.
I want that the tooltip displays every element in the next line, something like this:
But, instead I'm getting this:
I got 3 elements per line, and I don't want that. I want one element/line.
My code is as follows:
app.component.ts
items=['15-09-2020: 200','16-09-2020: 200','17-09-2020: 200', '18-09-2020: 200'];
newItems = this.items.join("\r\n");
app.component.html
<div class="col col-sm-2" matTooltipPosition="after" matTooltip="{{ items}}"></div>
Check this example that is not working for me:
Stackbliz
Source : https://www.angularjswiki.com/material/tooltip/
It's a bit late, to people who want to have breaklines in the tooltip,
you create a custom class in your global CSS and add this class with "matTooltipClass".
HTML
<button mat-raised-button
matTooltip="Multiline Tooltip 
 This is second line"
matTooltipClass="multiline-tooltip">
Multiline tooltip
</button>
Global CSS
.multiline-tooltip{
white-space: pre-line;
}
You can also add in your specific component, you should add
encapsulation: ViewEncapsulation.None
to your component.ts
#Component({
selector: 'app-tooltip',
templateUrl: './tooltip.component.html',
styleUrls: ['./tooltip.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class TooltipComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
https://siderite.dev/blog/styling-angular-material-tooltips.html/
Hope this can help others
The answer from Asaf is working perfectly for me.
Angular 14
matTooltip="Component: Test
Last updated date: 2023-01-17T09:17:02.753Z"
Mattooltip
I have fixed this in my project using
So, what you'll need to do is:
newItems = this.items.join("
");
Another thing, you need to change this:
matTooltip="{{ items}}"
To this:
[matTooltip]="items"

Styling child components template from parent component css angular

How to force CSS of child component from parent using ::ng-deep or something?
I have parent component where I put child component:
....parent.component...
<app-likes></app-likes>
.....parent.component......
Not inside that likes component there is he following HTML:
<div class="mainDiv">
<div class="secondDiv"><i class="far fa-heart fa-3x"></i></div></div>
Now I want to set color of fa-heart class to white from parent parent.component.css.
How can I do that?
You can do this way, in the css of the parent component:
parent.component.css:
:host ::ng-deep .fa-heart {
color: red;
}
or
:host ::ng-deep app-likes .fa-heart {
color: red;
}
Well I will go against the folks above and suggest that you don't do this.
If you consider the component an isolated building block in your app, you would consider it an advantage, that it looks the same in every place you use it. Using ::ng-deep to override this behaviour will cause you trouble in larger apps.
Angular promotes using #Inputs as the interface of passing data into the component. My suggestion is to use #Input to modify the view. Or, if in larger contexts you can use Dependency Injection to provide a token that specifies a theme for all children of a component.
<app-likes theme="white"></app-likes>
#Component({selector: 'app-likes'})
class AppLikesComponent {
#Input() theme: string;
#HostBinging("class") get themeBinding() {
return 'theme--' + this.theme;
}
}
You could set the ViewEncapsulation option in the parent component to remove the shadow DOM. This essentially allows the child component to use the selector definitions from the parent component.
Try the following
Parent component
import { Component, ViewEncapsulation } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
encapsulation: ViewEncapsulation.None // <-- no shadow DOM
})
export class AppComponent {
}
Parent CSS
.fa-heart {
color: white;
}
Working example: Stackblitz

How to access local css class names from within the angular component

I need to access the generated css classname from within an angular component, in order to style a 3rd-party component.
Angular does some magic transformations on the local css classnames to enable scoping. I need to apply some custom styles to an ngx-datatable component. To do this, I need to pass it custom classnames. Because of what angular does to the classnames, these no longer match.
Adding the classnames to the global scope or using ::ng-deep both work, however I would rather not break the encapsulation.
dashboard-component.ts
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent {
getRowClass(row){
return 'my-class';
}
}
dashboard-component.scss
.my-class {
background: green;
}
dashboard-component.html
<ngx-datatable
[rowclass]="getRowClass"
></ngx-datatable>
The way I see it I should be able to access some reference to the css class from within the component, say this._styles, which will then carry the generated name of the class at runtime, so I can do
getRowClass(row){
return this._styles['my-class'];
}
I think you are not able to propagate your styles to ngx-datatable.
You can use encapsulation: ViewEncapsulation.None within your #component but make sure you use it carefully as it will lead to some weird css behaviours.
Next, What you can do is create a container for your dashboard.html file like:
<div class="dashboard-container">
<ngx-datatable></ngx-datatable>
</div>
and inside your dashboard.scss you can reference the parent container
.dashboard-container {
.my-style{}
}
Just put the css classes in the global style file ,otherwise you will need to use ::ng-deep,so my advice to put ngx-datatable in the global style file
check the ngx-datatable demo asset/app.css where the did the same
another option you can set the encapsulation: ViewEncapsulation.None on the component the the class name will be the same
#Component({
selector: "app-demo",
templateUrl: "./demo.component.html",
styleUrls: ["./demo.component.scss"],
encapsulation:ViewEncapsulation.None
})
export class DemoComponent implements OnInit {
demo.component.scss
ngx-datatable {
.green-color {
background:green;
& div {
color :#fff;
}
}
}
set the encapsulation to none or put the style in global style file are the same here because both ways will be the style globally without any change
demo 🔥

Prevent global CSS being applied a component in Angular 5

In .angular-cli.json, I got some global styles:
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.css",
"../node_modules/font-awesome/css/font-awesome.css",
"../node_modules/ng2-toastr/bundles/ng2-toastr.min.css",
"styles.scss"
],
But I don't want any of them being applied to a specific component - is it achievable?
EDIT 1:
Unfortunately, overriding the CSS style in the component style won't work because the HTML in the template of the component is fetched from a Web API backend - I guess I can't realistically override every possible class/selector?
CSS cascades (hence the term, Cascading Style Sheets).
for full browser support your only option is to override selectors.
another option, not as common due to lack of support on IE and Edge,
is the all property.
html
<div class="component-container">
<!-- your components html template ... -->
</div>
css
.component-container {
all: initial;
all: unset;
}
Using component styles
For every Angular component you write, you may define not only an HTML template, but also the CSS styles that go with that template, specifying any selectors, rules, and media queries that you need.
One way to do this is to set the styles property in the component metadata. The styles property takes an array of strings that contain CSS code. Usually you give it one string, as in the following example:
#Component({
selector: 'app-root',
template: `
<h1>Test Text</h1>
`,
styles: ['h1 { font-weight: normal; }']
})
export class AppComponent {
/* . . . */
}
styleUrls
One or more URLs for files containing CSS stylesheets to use in this component.
styleUrls: string[]
styles
One or more inline CSS stylesheets to use in this component.
styles: string[]
You can use the :not selector in your global CSS.
You'd have to play around with it to get the desired behaviour but it should be something like this:
h1:not(.my-specific-class) {
font-size: 3rem;
}
You can use angular built in shadowDom API from view encapsulation. Which will make your component elements loaded inside a separate DOM tree so global css wont affect your component elements.
#Component({
selector: 'app-root',
template: `
<h1 class="head-app">Test Heading</h1>
`,
styles: ['./app.component.scss'],
encapsulation: ViewEncapsulation.ShadowDom
})
export class AppComponent {
/* . . .
You can define styles at component level using styleUrls property inside the scope of #Component. Please have a look at below code:-
#Component({
selector: 'app-manageUser',
templateUrl: './manageUser.component.html',
styleUrls: ['./manageUser.component.css'],
providers: [UserService]
})

Using ngStyle on the body tag on the main index.html in angular 2

I couldn't find a way to use ngStyle on the index.html in the body tag using angular 2.
like on index.html:
<body ngStyle="bodyStyle">
Demo text
</body>
The only way I found is using "encapsulation: ViewEncapsulation.None" in the component, however, only works using standard css class but not using a variable or function as ngStyle,
Like, on the component styles:
body {
background: red;
}
I also found something similar on angularjs as the link below.
http://plnkr.co/edit/7cwAeGMsCYA8HIrWbl7d?p=preview
Is possible to have the same result in angular 2 as the link above ?
There is no way to do that. ngStyle only works in the template of an Angular component. <body> can't be inside a components template.
You can use https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style instead.
Another way would be to use 'body' as selector of your AppComponent and apply styles using #HostBinding()
#Component({
selector: 'body',
...
})
export class AppComponent {
#HostBinding('style.background-color')
backgroundColor:string = 'red';
}

Resources