Importing style sheets in angular4 - css

Am trying upgrade my project from angular JS to angular 4. I have style sheets which i have used in angular JS project.
This is my folder structure
I created components using angular CLI.
Everything works perfect but i don't know how to use my styles in angular 4 project.
Can some one explain how i can use my styles globally? and also only in certain components?

You can add your styles within the angular-cli.json:
"styles": [
// Your styles go here
]
This is for global styles. Local styles (for a certain component) are within the accordant CSS-file, which belongs to your component, e.g. foo.component.css. By default each component has the following annotation:
#Component({
selector: 'app-foo',
templateUrl: './foo.component.html',
styleUrls: ['./foo.component.css'],
})
So, foo.component.css contains the CSS for the component FooComponent.
Take a look here:
Component Styles
Global styles

Apart from adding the css file to angular-cli.json as shown by #pzaenger you can also add it to index.html page of your app as shown below :-
<link rel="stylesheet" type="text/css" href="node_modules/bootstrap/dist/css/bootstrap.min.css" />
OR
you can even import it into an existing CSS file in your app by adding the #import statement at the top of that file as shown below :-
#import "~bootstrap/dist/css/bootstrap.min.css";
This way you can also add CDN links of the CSS file which cannot be done in angular-cli.json file. You can find a more elaborated explanation at this link.

Related

Vuejs Does Not Scope Style Imports

Vuejs Scoped applies to the who application instead to one component as per documentation. It does not work for imports, i does not why? or maybe it is supposed to be like that?
<style scoped>
#import url("https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.min.css");
</style>
I want to do the following;
Use both Bulma and Vuetify together
Use any style i want in any component ireegardless of the main style imported in main.js

Global styling vs local styling in VueJS

I'm building a project with .vue files which make it possible to write the CSS (SASS), JS and HTML in the same file.
I've decided to have some global components written in SASS on a assets/styles/app.scss file which will load my grid, variables and mixins.
On top of that, I want to be able to write some local SASS rules depending the component / page I'm on, seems pretty logical to want both in a project ...
Locally it looks like this:
<template>
</template>
<script>
</script>
<style lang="scss">
#import "assets/styles/app";
.my-style {
color: $my-variable;
}
</style>
It actually works, for instance I can use $my-variable in my local .vue file or any mixin I want. The problem is a VueJS project will grow and components will go together to display a page.
I noticed the global styling was loaded on each component, and the same rule is present in 5x, 10x when I open my chrome developer tool. This is still a very small project; all my styles are basically duplicated and loaded by the browser each time I add a component to the same page.
How do you avoid to load multiple times the global styles, while being able to use global SASS code in each components?
I've never worked with local mixed with global styling before, I preferred to just abstract totally the styling into a separated structure, but this is way more convenient to code with everything local in the same place.
What am I doing wrong here?
Detail: I'm on NuxtJS but I believe this issue is more related to VueJS overall.
Basically, every time you do an #import in your components it appends another copy to the main CSS file that Webpack generates.
Assuming you have the Webpack SCSS loader properly configured (which I believe you do since it compiles), you should be able to import the SCSS file once in your app.vue and the SCSS compiler will find it when it appends all other CSS.
For example, getting global fonts and mixins:
<style lang="scss">
#import url('https://fonts.googleapis.com/css?family=Lato:300,400,400i,700,900&subset=latin-ext');
#import "#/scss/mixins.scss";
</style>
Then create your CSS for each component inside the component's <style> section. Just make sure you add the lang="scss" so it all compiles.
You might also want to look into scss-resource-loader for Webpack. I think this is in the newest CLI builds, not sure about Nuxt.
in App.vue
<style lang="scss">
#import "assets/styles/common.scss";
</style>
OR
import compiled sass to css file in main.js
import './assets/styles/common.css';

Prevent CSS overwrites from web components in parent page

I created a web component using Angular Elements (6.0.3). When I use the web component in another website, the webcomponent overwrites the styles of the parent page since it also uses Bootstrap. I know that there is the view encapsulation principle, but as far as I know the "Native" encapsulation is not yet fully supported. So for now I am using the default "Emulated".
I found out that if I add :host ::ng-deep in front of my styles, they are only applied to the web component itself which is great. However, all css and scss files that I load in angular.json seem to be overwriting the parent page too. Is there any way I can prevent this behaviour from imported style-files?
My style-imports in angular.json:
"styles": [
"node_modules/intl-tel-input/build/css/intlTelInput.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/angular-calendar/css/angular-calendar.css",
"src/styles.scss",
"node_modules/font-awesome/css/font-awesome.min.css",
"src/assets/css/wizard.css",
"src/assets/css/calendar.css",
"src/assets/css/ng2-select.css"
]
The 'styles' imports in the angular.json are for styles you wish to define globally to the whole app. To use ViewEncapsulation you'll need to link their stylesheets inside of their components like so:
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
})

Keeping CSS out of JS in Angular 2/Angular-CLI

By default, Angular 2 compiles the CSS into JavaScript, especially when using WebPack as in Angular-CLI. I would rather this not happen for a couple of reasons.
The first reason is that when I'm developing, I find it really helps to be able to see in the developer tools exactly what style sheet a specific style rule was coming from and what line number it was on. The second reason is that I think compiling CSS into the code kind of misses the point of good CSS, which is that you can apply a different style sheet and have an entirely different look and feel with the same markup.
Is there a flag somewhere that I can set to leave the CSS in .css files, where IMO it belongs?
This is the whole point of encapsulated components.
A component should have it's own styles encapsulated with it so it can be shipped with the styles.
Imagine you want to publish one of your components to be used by others, shouldn't it have its own styles with it ?
That means Angular needs a way to link those css to the component , thus seperates them into chunks and injects them into head tag.
To solve your problem though , you have couple of options :
1- Not using the Emulated Encapsulation :
Components by default have a property called encapsulation which is set to Emulated , you need to change it to None:
#Component({
encapsulation:ViewEncapsulation.None
})
Then , you can put all you css in the head tag your self like you'd do with a normal html page.
2- If the problem is theme ing , you can make your component themeable .
You can have a theme attribute for your component and then based on that change the styleing :
#Component({
selector:'my-component',
styles:[
`
:host{
[theme="blue"]{
change what ever you want :
h1{
color:blue;
}
}
}
`
]
})
And then , using this component would be like :
<my-component [attr.theme]='"blue"'></my-component> // would be blue theme
<my-component></my-component> // would be default
Go to your base Html file(where the root module, main app is injected) and link the CSS stylesheets in your header section.
Webpack will not include it in it's compiled/combined css file which is injected into the page. The css file will still be included at run time in the browser.
<html>
<head>
<base href="/">
<meta charset="utf-8">
<title>dummy</title>
<meta name="viewport" content="width=device-width">
//was not injected/modified by webpack
<link rel="apple-touch-icon" sizes="57x57" href="app/images/apple-icon-57x57.png">
//webpack's injected this below from other components's imported/inline css rules
<link href="index-c2cacb5fa3dfbca6116f4e4e63d5c3c7.css" rel="stylesheet"></head>
With angular-cli 1.6.5 you can do this:
ng serve --extract-css
You will still have the style-encapsulation features, but devtools will now point to the component css source file.
I use the angular-cli as well (v1.0.0-beta.22). When I am ready to build for production I run the following command:
ng build -prod -aot
This generates all my production-ready files (bundled, tree-shaken and minified etc). Of particular note is that it will generate two versions of the style sheets.
One in js:
styles.b2328beb0372c051d06d.bundle.js
And another version is plain css:
styles.4cec2bc5d44c66b4929ab2bb9c4d8efa.bundle.css
I run some post-processing on the css file with gulp and use the css version for my production build. I am not sure if the same holds true for lazy loading (where the cli will produced different chunks), but it works for sure when lazy loading is not being used (I haven't launched a production-ready project yet with lazy loading).
I also tried a build with JiT compilation:
ng build -prod
It also produced the raw/minified version of the css style sheet.
Now, I know for sure the folowing does NOT work:
ng build
This will produce all the css embedded within js file, styles.bundle.js.
Since you want to use the raw css file during development, the only workaround I can think of is that you run ng build -prod in order to get the css file. Copy/paste this manually into your assets folder. Run "format" on the file to un-minify the file. Then do a normal build with a modified index.html file referencing your raw css file, and removing the styles.bundle.js script reference. Not pretty, but it might work.
Put a wrapper class in html example-
<div class="component-1-wrapper">
all yout html here inside component-1-wrapper
</div>
Structure your sass(scss) in the following way. Since your styles are wrapped inside component-1-wrapper, therefore it will apply only to component-1-wrapperclass
.component-1-wrapper{
// all the styles for component-1 here
.class-hello{
// styles
}
}
You can compile your css with sass and put all the css(seperated by modules) in seperate folder.Start the filenames by _, sass can import them:
You can refer your styles-main.scss in app.ts file
#component({
styleUrls:['styles/styles-main.scss']})
The style-sheets will be structured this way and individual component's class styles will be applied to particular component since there is a wrapper class in html
Hope it helps!!!!!!

Why do the styles appear embedded on inspect element in Angular 2

I downloaded a free HTML theme named dashgum from the internet. I'm implementing it for an Angular2 application using angular-cli. I converted the css files to .scss and pasted the code to the angular application. I then imported the files in the global styles file named styles.scss to apply the styles to the application like this:
#import url('./scss/bootstrap.scss');
#import url('./scss/font-awesome/css/font-awesome.scss');
#import url('./scss/zabuto_calender.scss');
#import url('./scss/gritter/css/jquery.gritter.scss');
#import url('./scss/lineicons/style.scss');
#import url('./scss/style.scss');
#import url('./scss/style-responsive.scss');
The problem that I'm facing during debugging is that all the styles appear as embedded styles in the browser like this (notice the style tag):
I want the style to appear as external styles while inspecting like in the theme. Please notice it in the following screenshot:
These are the default settings in Angular 2 as I made no apparent changes for the styles to appear embedded when inspecting. Is there any known way to change the settings in Angular 2 for the styles to appear as external styles when inspecting? The embedded styles make it harder for me to debug. Any help pointing out towards the solution would be appreciated.
My first advice (like official Angular CLI documentation says) is to put your global library inside .angular-cli.json like this:
...
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"../node_modules/font-awesome/css/font-awesome.min.css",
"styles.scss"
],
...
Then just run the app with the --extract-css parameter to see in the browser inspector the source files:
ng serve --extract-css
And you will have this:
I have learned that the styles imported in the global styles.scss file always appears embedded when inspecting in the browser. If we want the css to appear as external styles, we will have to use it in components.
Edit:
See toioski's answer above.

Resources