Fails to style with styleUrls in Angular component's scss file - css

I selected the scss option on a new Ionic Angular app. It's html container holds three tab pages. The scss stylesheet in the container component controls the styles for all pages. The global.sccs only contains imports, no styling and doesn't import the container's scss.. The container component implements OnInit.The stylesheets in the 3 tab page components are created empty.
I cannot change the style of any of the 3 tab pages by adding styles to their stylesheets. It continues to use the container's stylesheet. The selector for the style is in the container's html:
explore-container.component.html
<div id="container">
<strong>{{ name }}</strong>
...
</div>
The explore-container.component.ts file:
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-explore-container',
templateUrl: './explore-container.component.html',
styleUrls: ['./explore-container.component.scss'],
})
export class ExploreContainerComponent implements OnInit {
#Input() name: string;
constructor() { }
ngOnInit() {}
}
The tab page html uses the selector for the container component:
tab1.page.html
...
<app-explore-container name="Tab 1 page"></app-explore-container>
</ion-content>
The tab1.page.ts file:
import { Component } from '#angular/core';
#Component({
selector: 'app-tab1',
templateUrl: 'tab1.page.html',
styleUrls: ['tab1.page.scss']
})
export class Tab1Page {
constructor() {}
}
I have reviewed the docs about external stylesheets and encapsulation but I'm still lost. Why can't I just add a style to the scss in the tab page's own presently empty scss file? Eg., why doesn't inserting styles into the page component's scss:
tab1.page.scss
#container strong {
font-size: 40px;
}
override this in the explore-container.component.scss?
#container strong {
font-size: 20px;
}
Am I missing an import somewhere? If so, where?

Related

How to dynamically change styleUrls or style in Angular?

I want to allow users to customize colors and some styles in Angular application. For that I want to make something like this
Structure:
component-one
  folder-with-css-files
    style-for-component-1-for-client1.css
    style-for-component-1-for-client2.css
    style-for-component-1-for-client3.css
    style-for-component-1-for-client4.css
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.style-for-component-1-for-client{clientId}.css'],
})
export class AppComponent implements OnInit {
clientId: string;
ngOnInit(): void {
// pseudocode
clientId = service.fetchClientId() // for example
}
}
How I can achieve that? I want to have some css files for every component and depend on user id I want to assign them to styleUrls. Someone can tell me how to do it?
You can use scss and wrap every stylesheet in a different class then based on the user’s selection change the class of your body.
Something like:
DarkMode.scss
.darkMode{
your first css here…
}
LightMode.scss
.lightMode{
your second css here…
}
index.html:
<body class="lightMode"></body>
Doing the above will by default apply the lightMode styling and if you remove the classes of your body in any of your components and replace it with darkMode then the darkMode styling will apply.
Adding/Removing class to/from body:
constructor(private renderer: Renderer2) {}
addClass(){
this.renderer.addClass(document.body, 'className');
}
removeClass(){
this.renderer.removeClass(document.body, 'className');
}
Adding/Removing the class does not have to be only in the index.html file, all you need to do is have a tag with a certain class that wraps around your whole code. For example in one of your components:
component.html:
<div [class]="className">
the rest of your html here...
</div>
component.scss:
.greenDefault{
green default css here...
}
.redDefault{
red default css here...
}
.greyDefault{
grey default css here...
}
component.ts
className: string;
changeStyle(class: string){
this.className = class;
}

How to add custom css to the single Toast message in Angular?

MY QUESTION :
How to add css to the single Toast used in components in Angular, as there can be multiple toast but i want to change a single toast?
Eg toast image : example toast
I want to add my css to the particular toast message.So, that i can align message text in the center i.e File Import started..
how my Angular directory looks like
| app
|
|-components
| |
| |-test [/app.ts , /app.css]
|
|style.css
What I Tried :
I added the following codes to my CSS and TS code :
my rough app.css code
.test {
text-align : center !important // I tried without ! important also
}
my rough app.ts code
import { Component } from '#angular/core';
import {ToastrService} from 'ngx-toastr';
#Component({
selector: 'my-app',
templateUrl: './app.html',
styleUrls: [ './app.css' ]
})
export class app {
constructor(private toastr: ToastrService) {}
showSuccess() {
// I tried \" test \" also
this.toastr.success('<span class="test">File import started</span>', '', {
enableHtml : true //even I have added the messageClass : 'test'
});
}
}
HOW IT WORKED BUT I DON'T WANT THESE WAYS :
by putting my css code into the style.css (main global css) (X I don't want to change my main style)
by adding ::ng-deep .test instead of .test : this is harmful it will change all my toast-dialogue.
by adding encapsulation: ViewEncapsulation.None in #component : but this will change my other Css.
by using <center> tag : still i don't want to do it because it will fix my issue but what if i want to add multiple css.
How can I achieve this?
You need to apply titleClass and messageClass when your toast is used and overwrite the css background-image to align icon and text:
showSuccess() {
this.toastr.success("Hello world!", "Toastr fun!", {
titleClass: "center",
messageClass: "center"
});
}
Add css class in your global styles:
Styles.css:
.center {
text-align: center;
}
.toast-success {
padding-left: 80px;
text-align: center;
background-position: 35% !important;
}
Or use with :ng-deep if you want to add it in your component's styles css:
app.component.css
:ng-deep .center {
text-align: center;
}
Other alternative is create your own toast component extending Toast and use it customising its template adding a css class for centering the text.
Using a Custom Toast
The issue in this case is that you can't override the css background-image property to align icon and text. You can only do that in styles.css
Changing default icon styles
Here's the Demo:
https://stackblitz.com/edit/ngx-toastr-angular2-4pqrqw
You can use the titleClass property to apply the css class on the toast message.
import {ToastrService} from 'ngx-toastr';
#Component({
selector: 'my-app',
templateUrl: './app.html',
styleUrls: [ './app.css' ]
})
export class app {
constructor(private toastr: ToastrService) {}
showSuccess() {
this.toastr.success('File import started', '', {
messageClass: 'test'// this will apply the test class to the toast title.
});
}
}

how to replace angular theme CSS stylesheet for whole app?

First I couldn't import css through index.html and I get MIME type error:
enter image description here
Refused to apply style from 'http://localhost:4200/css/pink-bluegrey.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
if i try to import it through angular.json then I can't insert ID tag id="themeAsset".
Reason why I want to add id is because i want to do this from https://material.angular.io/guide/theming
function changeTheme(themeName) {
document.getElementById('themeAsset').href = /path/to/my/${themeName}.css;
}
so i could change style for whole app styles by click instead of adding classes to every component
Working Stackblitz :- https://stackblitz.com/edit/angular-jrkmhn
I placed my css inside assets folder i.e. myStyles.css
CSS :-
.myDiv {
background-color: black;
}
index.html
<link id="myLink">
<my-app>loading</my-app>
app.component.html
<div class="myDiv">Css Will Load</div>
<button style="margin-top: 2em" (click)="changeTheme('')">Change Theme</button>
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
changeTheme(themeName) {
var elem = document.getElementById('myLink');
elem.setAttribute('href','./assets/myStyles.css');
elem.setAttribute('rel','stylesheet');
elem.setAttribute('type','text/css');
}
}

Angular 6 not applying scss styles

I have a component page and corresponding style sheet, however the classes in the component.scss dosen't apply to the page. There are no errors, I am still wondering why?
This is my product-detailpage.component.html
<div>
<h1>Product Detail Page</h1>
</div>
This is the .ts file
import { Component, OnInit } from '#angular/core';
import {ActivatedRoute} from '#angular/router';
import {ProductdetailService} from '../productdetail.service';
#Component({
selector: 'app-product-detailpage',
templateUrl: './product-detailpage.component.html',
styleUrls: ['./product-detailpage.component.scss']
})
export class ProductDetailpageComponent implements OnInit {
constructor(private route: ActivatedRoute, private productData: ProductdetailService) {
this.route.params.subscribe(params => console.log(params));
}
ngOnInit() {
}
}
This is the .scss file
body{color:Red !important}
app-product-detailpage{
h1{color:red !important}
}
However one thing I noticed was if I make changes to the global styles.css it works fine. just to check I changed the body color to green and it works.
My angular app is configured to work with scss. what could be the reason? can some one suggest?
Your SCSS won't work for your HTML file product-detailpage.component.html.
The reason is Angular uses shadow DOM for components. That means the tags <body> and <app-product-detailpage> are nowhere to be found in your component.
As per the documentation, The style specified in the component can only be applied to its template, which excludes the component.
This is the reason why your styles are not working on the component from component's style.scss but are working fine from global style sheet.
One way of doing it is to use :host pseudo selector as per this documentation which allows to add styles on the container in which component is placed.
The documentation says -
The :host selector is the only way to target the host element. You can't reach the host element from inside the component with other selectors because it's not part of the component's own template. The host element is in a parent component's template.
Because default css encapsulation in Angular is Emulated(ViewEncapsulation.Emulated) so Angular will render out like below:
input[_ngcontent-c0] {
border-radius: 5px;
}
So if you want set style to the currently component, you can use Native option.
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation : ViewEncapsulation.Native
})
It will render like as:
input {
border-radius: 5px;
}
But finally I suggest you use global scss file to define style of <web component>.

Angular 4 - Not use styles from angular-cli.json

I have an angular 4 application where I have the global styles and scripts in angular-cli.json. Then I worked separately on the Landing page. After I turn the landing page into an angular component, I add all its styles in angular-cli.json as well. And now my landing page's bootstrap conflicts with global bootstrap in node_modules and my application breaks.
Currently angular-cli.json looks like this:
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"./dist/css/landing/bootstrap.min.css",
"./dist/css/landing/font-awesome.min.css",
"styles.css",
"./dist/css/AdminLTE.min.css",
"./dist/css/skins/_all-skins.min.css",
"../node_modules/froala-editor/css/froala_editor.pkgd.min.css",
"../node_modules/froala-editor/css/froala_style.min.css"
],
This is in landing.component.ts:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-landing',
templateUrl: './landing.component.html',
styleUrls: ['./landing.component.css']
})
export class LandingComponent implements OnInit {
constructor() { }
ngOnInit() { }
}
I am almost missing my deadline, I can not resolve the conflicts between two huge css files. I was wondering if I could keep my Landing Page styles separated from application styles. Any help will be largely appreciated. Thank you.
You could try encapsulate your landing page as follows.
ViewEncapsulation.Native will wrap your component and its styles within a shadow root. Change your component style file to scss and import those styles in component style file and delete them from .angular-cli.json.
#Component({
selector: 'app-landing',
templateUrl: './landing.component.html',
styleUrls: ['./landing.component.scss'],
encapsulation: ViewEncapsulation.Native
})
export class LandingComponent implements OnInit {
constructor() { }
ngOnInit() { }
}
landing.component.scss
#import '<path-to-dist>/dist/css/landing/bootstrap.min.css';
#import '<path-to-dist>/dist/css/landing/font-awesome.min.css';
When you inspect DOM, you'll see app-landing as encapsulated.
Edit
Alternatively, you can use ViewEncapsulation.Emulated which is default (you do not have to set it within metadata). What this will do is to create custom attributes with all the styles and add those attributes to your markup as well. Shadow DOM may not be supported in some browsers. Try both and if Emulated works for you, use that.

Resources