Because I'm using Webpack to also bundle my css and that my script tag is at the bottom of my HTML, on initial page load I get the content of the page without any of the styling.
Then all of a sudden the styling comes in when the script kicks in.
Webpack is very useful to help bundle the CSS but this behavior is quite unsettling and not really acceptable.
What are common ways to remedy this problem?
You can try using extract-text-webpack-plugin to break out the css in to their own files. That way you can add <link> tags yourself to those pages you wish to have their styles loaded before the JS is loaded. See stylesheets as separate bundle.
For webpack v4, mini-css-extract-plugin should be used instead of extract-text-webpack-plugin (source). There are usage examples on their README.
Related
I am very new to Angular and currently I am trying to add styling to an existing project.
The project has been constructed using components. So for each page there are 4 files,
mypage.component.css
mypage.component.html
mypage.component.spec.ts
mypage.component.ts
I can easily style the page by adding the styles to the css file in the component and the page style works perfectly.
However the issue is there are many pages that require the same styles again and again.
I can copy and paste the same styles to each css file and it works.
But this is not the most elegant or efficient way to do this.
I want to know what the correct way to add a global.css file so that it can be accessed by each page. So that way the css is only written once.
I have googled but haven't found anything that explains how to do it in simple ways.
Thanks
Angular adds the style.css/scss file by default to your project once you created it using the ng new command, and include it within the angular.json config file to be available across the components of the project.
So you can add any global styles within src/styles.css(or scss) file, to be implemented everywhere.
you can add your generic css into style.css/style.scss.
We have an Angular 8 single page web app deployed on the customer server. They set one of the CSP directive to: default-src 'self'. We build the Angular app using ng build --prod like any other Angular applications. After deploying, we get this error:
main-es2015.47b2dcf92b39651610c0.js:1 Refused to apply inline style because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.
Look into the html code on the browser, I see something like this:
As you can see, Angular actually use tag <style> to serve the css (please correct me if I'm wrong). This violates the CSP directive mentioned in the question.
After searching around, I think Angular/React is quite bad at handling this issue, those frameworks are not built with CSP in mind. You can check out Angular github page, there is an open issue for this. Now I'm searching for a solution to overcome this, of course changing CSP policy is not an option because the customers don't want to.
How can I tell Angular not to use tag <style> in production to serve css? I think to make it works we need to set Angular in a way that it will load the css files, and then use styles in those files instead of injecting <style> into html which causes CSP issue.
Edit 1: Our project is using scss.
Edit 2: After searching around, I have found out that Angular will inject your component's styles into the DOM by using <style> element. As shown here:
Now I have an idea, because for each compinent's style will be injeced into the DOM through <style> element, we can prevent this from happening by bundling all component's style .scss file into a single style.scss file. From the image above you can see that we always have an empty <style> element, so if this works, we will endup with only one <style> element and a <link> element that link to our global style scss file. We can have multiple way to remove that empty <style> element before the page got rendered by the browser.
Now I'm stuck at configuring custom webpack to make this happen. We cant use ng eject to get the webpack.config.js file since Angular CLI 6. I've been using Angular CLI 8 so the only way for me to add custom configuration into Webpack is to use custom-webpack npm. I cant find a good config file that has the same output as my desire, please help if you know how to config webpack to bundle all component's styles scss files in Angular into a global scss file.
I think this can be an acceptable answer for my question:
First of all, my recommendation is stay away from using styleUrls. Angular will inject styles of your component into the DOM using <style> element. Secondly, if it's possible, you should know / ask for the CSP policy on the deployment server/environment. What I have been doing to resolve the issue (my project is reletively small with just a couple dozen of components):
Copy (one by one) relative link of components, put them into angular.json, in styles attribute. This is because Angular will bundle all styles in this attribute as a single css/scss file. I copy one by one because the css/scss file was designed to work with Angular View Encapsulation in the first place. Gathering all of them into one place might introduct unexpected issue, this will break the UI. Whenever copy a component style and put into styles, I check if the UI breaks because of that. This will help me narrow down the root cause if such issue happens.
For each component, after copy its component style file's relative path into styles, I remove styleUrls in #Component. This prevents Angular from injecting <style> into the DOM.
Caveats:
Gathering all styles into one single file and load them at once might cause performance issue. Luckily my company project is relatively small.
Now you need to document the new way of making styling work in your project.
By default Gatsby drumps all the css required on a given html document into its header making css caching impossible:
import "./foo.css"
import "./bar.css"
results in:
<style data-href="/styles.f6ce41623bc6fbf912c0.css">
.foo{color:green}.bar{color:orange}
</style>
/styles.f6ce41623bc6fbf912c0.css contains exactly that stylesheet.
is there a way to keep foo.css and bar.css in separate files without loosing the ability to minify and autoprefix everything?
The functionality is called bundling, and Gatsby uses Webpack to do it. You could alter the Webpack configuration, but I’d say there is really no point in doing that.
Bundling and code-splitting resources is a crucial part of why Gatsby is so fast. By bundling the CSS for every page makes sure that only resources required by the current page are loaded. Gatsby also caches all of the resources it has loaded, so you don’t need to worry so much about resource economy.
I found a code snippet from a Gatsby issue comment, which replaces inline <style> elements with <link>s, but I wouldn’t recommend doing that without going through some performance measurement.
i'm busy with a Nativescript app, i'm using the core dark theme but would like to add some font-awesome glyphicons and custom css. I import the core dark theme in my global app.css but don't seem to be able to do anything more in that file after importing the theme... I've tried to add page-specific css by adding a component-common.css to a specific page but when I add the styleUrls: [...] declaration to the component declaration I always get a runtime error... Is it possible at all to use custom css ontop of the core Nativescript theme? If so how would I go about it (using css files not inline in the xml)?
Yes, it is possible to use both a theme and custom CSS files.
For example, check this sample where in the same time theme has been applied to the top CSS file.
Better check (and/or post) your runtime error - it might show you the reason why the app is throwing. Perhaps due to non-existing paths for your styleeUrls !?
No dust-me-spider. No firebug.
I have made a project and I want to export only the CSS which has been used in the project or page. I have tried, dust-me-spider and firebug, but these add-ons grab all the CSS of the project! I need to grab only the CSS which has been used and export it to another CSS file. Does any program exist for such a reason?
Its tricky because you can't know all of the javascript renderings on a page that would affect the css. I wrote my own plugin that i could run which would extract the visible css on the page and resort the css in order of cascading hierarchy. This is useful in that i can run it after any javascript action but it still requires investigation into the existing javascript. You are welcome to use it.http://stcreative.co.uk/tutorials/css_sorter/