Angular 2 external style doesn't get inlined to header - css

I have this component definition in typescript:
import {Component, ViewEncapsulation} from 'angular2/core';
#Component({
selector: 'my-app',
templateUrl: '/views/sandbox.html',
styleUrls: ['/styles/sandbox.css'],
styles: [`.wow { background-color: red; }`],
encapsulation: ViewEncapsulation.Emulated
})
export class SandBox { }
According to this article: http://blog.thoughtram.io/angular/2015/06/25/styling-angular-2-components.html
both the style in the styles section and in the external stylesheet should be inlined into the header by angular.
Unfortunately, the second does not get injected, angular injects only the one in the styles section.
I have tried accessing /styles/sandbox.css from browser, it is fine. Angular is also able to access /views/sandbox.html so i have no idea why it is not happening.
I am using: "angular2": "2.0.0-beta.2" (latest beta AFAIK)

I made some tests and strangely styles from the sandbox.css only applies if you use a relative paths within the styleUrls attribute:
#Component({
selector: 'my-app',
templateUrl: '/views/sandbox.html',
styleUrls: ['../styles/sandbox.css'],
styles: [`.wow { background-color: red; }`],
encapsulation: ViewEncapsulation.Emulated
})
export class AppComponent {
constructor() {
}
}
Edit
After having a look at the source code, Angular2 prevents from using absolute path for the styleUrls. See this line:
https://github.com/angular/angular/blob/master/modules/angular2/src/compiler/style_url_resolver.ts#L12
export function isStyleUrlResolvable(url: string): boolean {
if (isBlank(url) || url.length === 0 || url[0] == '/') return false; // <-----
var schemeMatch = RegExpWrapper.firstMatch(_urlWithSchemaRe, url);
return isBlank(schemeMatch) || schemeMatch[1] == 'package' || schemeMatch[1] == 'asset';
}
Hope it helps you,
Thierry

The Best way to fix this is use another css file for your component and add it to your StyleUrls list. Cleaner and will scale as you components grow.

You can use systemjs and commonjs module dependencies loader, to load templates, styles and other files.
in commonjs moduleId : module.id
in systemJs __moduleName
import {Component} from '#angular/core';
#Component({
moduleId:module.id,
selector: "exf-header",
templateUrl: "header.html",
styleUrls:['header.css']
})
export class HeaderComponent {
}

Related

Angular How to load css from server

I want to try to load css from a server/external source intro angular. I'm trying to use the DomSanitizer already but without succes. The stylesheet is shown inside the network tab of chrome but the html does not apply the stylesheet.
chrome networktab:
Inside the TS file:
import {Component, OnInit, ViewEncapsulation} from '#angular/core';
import {DomSanitizer} from "#angular/platform-browser";
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None,
})
export class AppComponent implements OnInit{
title = 'angulardynamicss';
cssUrl = 'http://localhost:8080/api/csspoc/asFile'
constructor(public sanitizer: DomSanitizer) {}
ngOnInit(): void {}
}
And HTML looks like:
<link rel="stylesheet" [href]='sanitizer.bypassSecurityTrustResourceUrl("http://localhost:8080/api/csspoc/asFile")'>
<p class="test">hello</p>
The stylesheet file contains:
.test {
background-color: blue;
}
p{
color:yellow;
}
Why do you inject it in the AppComponent? Can you not just add the <link> tag in the <head> of your index.html?

CSS file of a component within a library does not get loaded with the component in angular app

I have developed a library in an angular application (which is generated using angular cli) and the library contains a component with its own template file and stylesheet. However, when I load the module in the app.module.ts and run the app (using ng serve for simplicity), the styles within the stylesheet are not rendered.
The library is generated using ng generate library
The library is contained within the projects directory of the app
The component is present within <name of the component>/src/lib directory
The app.module.ts file contains the following code:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { GuitarChordGeneratorModule } from 'projects/guitar-chord-generator/src/public-api';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
GuitarChordGeneratorModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Below is a snippet from the guitar-chord-generator.component.ts file:
import { Component, OnInit, Input } from '#angular/core';
import { Chord } from './chord';
import { GCSGConfig } from './gcsgconfig';
#Component({
selector: 'lib-guitar-chord-generator',
templateUrl: './guitar-chord-generator.component.html',
styles: ['./guitar-chord-generator.component.css']
})
The image below is the directory structure of the app.
As you can see that guitar-chord-generator.component.css is the CSS file for the component.
Your component has
styles: ['./guitar-chord-generator.component.css']
The styles property takes an array of strings that contain CSS code.
You should be using styleUrls
styleUrls: ['./guitar-chord-generator.component.css']

Angular 5 custom component CSS

I have a CSS file I ONLY want to be loaded when a component is on the page.
I have tried the following:
#Component({
selector: 'testview-testview',
templateUrl: './templates/testview.html',
styles: [
"../../../assets/vendors/custom/reveal.js-3.6.0/css/reveal.css",
"../../../assets/vendors/custom/reveal.js-3.6.0/css/theme/black.css"
],
})
However without any luck. Does anyone know of a way to do this?
EDIT
So i am attempting to follow the answer below
Here is my folder structure:
My Component now looks like this:
import {Component, OnInit} from '#angular/core';
declare var Reveal: any;
#Component({
selector: 'testview-testview',
templateUrl: './templates/testview.html',
styleUrls: ['./templates/testview.css'],
})
export class TestviewComponent implements OnInit {
constructor() {
}
ngOnInit() {
Reveal.initialize({});
}
}
And my testview.css file looks like this:
#import url("../../../assets/vendors/custom/reveal.js-3.6.0/css/reveal.css");
#import url("../../../assets/vendors/custom/reveal.js-3.6.0/css/theme/black.css");
You have to inside the urls inside array of styls: styleUrls instead of styles
SO
#Component({
selector: 'testview-testview',
templateUrl: './templates/testview.html',
styleUrls: [
"../../../assets/vendors/custom/reveal.js-3.6.0/css/reveal.css",
"../../../assets/vendors/custom/reveal.js-3.6.0/css/theme/black.css"
],
})
EDIT:
#Component({
selector: 'testview-testview',
templateUrl: './templates/testview.html',
styleUrls: ['./templates/testview.css'
],
})
in you css ./templates/testview.css import files
#import url("../../../assets/vendors/custom/reveal.js-3.6.0/css/reveal.css");
#import url("../../../assets/vendors/custom/reveal.js-3.6.0/css/theme/black.css");

Angular Universal CSS imports not working

I'm just testing out how Angular Universal handles the imports of third party JavaScript and CSS libraries. For ease of use I tried with jQuery and Bootstrap.
I'm using the Universal Starter repo https://github.com/angular/universal-starter and installed jQuery and Bootstrap through npm.
In my app.component.ts I included jQuery like so and it works perfectly.
import { isBrowser, isNode } from 'angular2-universal'
var jQuery: any = require('jquery');
...
#Component({
changeDetection: ChangeDetectionStrategy.Default,
encapsulation: ViewEncapsulation.Emulated,
selector: 'app',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
title = 'ftw';
ngOnInit(): void {
if (isBrowser) {
jQuery('#universal').css({'color': '#FF0000', 'font-size': '25px'})
}
}
}
Though when I want to import a css file it won't work properly. I'm importing it within my app/client.ts file as follows.
...
// Angular 2
import { enableProdMode } from '#angular/core';
import { platformUniversalDynamic } from 'angular2-universal/browser';
import { bootloader } from '#angularclass/bootloader';
import { load as loadWebFont } from 'webfontloader';
import 'bootstrap/dist/css/bootstrap.css';
// enable prod for faster renders
enableProdMode();
...
The actual Bootstrap css is within my Webpack bundle but my HTML isn't styled in any way. Anybody had a similar problem with this and knows how to fix this issue?
In order to make import 'bootstrap/dist/css/bootstrap.css'; work, you'll need style loader, which is not installed with universal-starter repo. Sidenote: If you use bootstrap.css as is, and you want to use universal-starter, you can copy bootstrap.min.css into assets folder and add a link tag for it in index.html.
Go to the angular-cli.json or angular.json file at the root of your Angular CLI project folder, and find the scripts: [] property, and include the path to jQuery as follows:
"scripts": [ "../node_modules/jquery/dist/jquery.min.js",
"../node_modules/bootstrap/dist/js/bootstrap.js"]
Now, to use jQuery, all you have to do is to import it in whatever component you want to use jQuery.
import * as $ from 'jquery';
(or)
declare var $: any;
import { Component, OnInit } from '#angular/core';
import * as $ from 'jquery';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
ngOnInit()
{
$(document).ready(function(){
// your code
});
}
}

Writing css for Angular 2 View encapsulation via styleUrl

I am making a simple hello world app (currently migrating from angular 1) I used angular-cli to generate my components and it created a stylesheet and linked it in my component via styleUrls. None of my styles apply the way I think they are supposed to unless I do "viewEncapsulation.none." Is there something I'm missing? Or is there a better way to write out css for this?
If I use the default encapsulation ( ViewEncapsulation.Emulated or even native) my styles don't show up at all.
import { Component, OnInit } from '#angular/core';
import { ViewEncapsulation } from '#angular/core';
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
encapsulation: ViewEncapsulation.None,
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
My CSS looks like this:
.app-header{
display: block;
opacity:0.2;
}
You need to use this css:
:host() {
display: block;
opacity:0.2;
}
Don't manipulate the component tag, this tag scope belongs to the parent component who uses it. manipulate only tags inside your html template component.
I think you need to set module:module.id in the component declaration for angular to search for the file in the right location. Have you verified that the CSS gets loaded in the non working case?
I am assuming you are using the app-header css somewhere in header.component.html? Try the below code.
import { Component, OnInit } from '#angular/core';
import { ViewEncapsulation } from '#angular/core';
#Component({
module: module.id,
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
constructor() { }
ngOnInit() { }
}

Resources