I'm using Angular CLI and it's preconfig'ed webpack bundle. I have a bit of HTML that's inserted into a template via [innerHTML] and want to apply styling to it, but I notice that the final styles.bundle.js doesn't contain the style I write. I assume webpack is smart and strips out the CSS definition since it's not in any template, but being added via JS.
In my template I simply have this:
<div [innerHTML]="message"></div>
Which gets a value in the controller such as:
this.message= '<p class="notice">Your account was successfully activated!</p>';
And while I have .notice defined in my .less file, it doesn't appear in the style bundle. When I had the notice class previously in the template itself, it worked fine.
Is there a way for me to keep this from happening? Should I be coding differently? Or is the problem elsewhere and not what I think it is?
Since the HTML being added by innerHTML is not directly in the scope of Angular, I needed to add /deep/ selector before .notice in my less file, to make sure children can access the CSS value.
Related
I'm on Vue.js v2. I have a CSS stylesheet stored as a string in a variable.
import sitePackCss from '!!raw-loader!sass-loader!../../app/javascript/styles/site.sass';
I need to create a tag from my component.
<style v-html="sitePackCss" />
OR
<style>{sitePackCss}</style>
When I do either of these, I get the following error in the console:
Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <style>, as they will not be parsed.
How do I get this tag onto the page?
NOTE: I know this is a hacky, non-preferred way to include styles. This solution will only get used in the context of storybook, where I need to include specific CSS files for specific stories (without storybook/webpack adding them to every story). If I use normal webpack loaders, each tag is added to every story. Importing the styles as a string is the only way I've found to sidestep that behavior.
Try to add the style to the src tag of the style in your SFC :
<style lang="sass" src="../../app/javascript/styles/site.sass">
</style>
This seems to work!
import sitePackCss from '!!raw-loader!sass-loader!../../app/javascript/styles/site.sass';
In template:
<component is="style" type="text/css">${sitePackCss}</component>
Note: the sass files have references to fonts that were not working correctly using this technique. I had to update the staticDirs config to make those paths work. https://storybook.js.org/docs/react/configure/images-and-assets
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.
I read posts about meteor file loading order.
But if I wish to make sure a CSS snippet will override any other CSS (loaded later for another template) How can I make sure the CSS snippet has final word for a template?
(put it in a top folder non lib would anyway load it before the following templates. And using another template, the problem will be the same from the POV of that other template)
Some people suggest, and I like it, to have a CSS file for each template, so we know what CSS is used for that template and we do not build a big large CSS, even if, meteor consolidate them.
I like the convention of adding a unique class name to each template. Here's an example:
<template name="posts">
<div class="__posts">
{{#each posts}}
<p>{{text}}</P>
{{/each}}
</div>
</template>
Then in your css you can specifically target instances of the posts template like this:
.__posts p {
color: blue;
}
You don't, of course, have to use the double-underscore but I find that makes a convenient indicator that the class is unique to a template. Also note this technique solves another common problem: how to identify which template rendered which portion of the current DOM.
I'm using GWT in a new project that I'm working on and I'm facing a problem. Some of the CSS rules were defined into the XML file and not into a CSS file.
The problem is that when GWT compiles the code, my name classes defined into my XML file are changed to a new random ID.
Stuffs like GKA-VPPBPE or GKA-VPPBLE
Is there is a way to keep the original name instead of the generated ones?
The generation of obfuscated css classnames is a feature.
GWT has enabled CSS obfuscation activated by default. This will help reduce the download size and also reduce collision of css-classnames.
You can disable this in general:
<set-configuration-property name="CssResource.style" value="pretty"/>
Or for some classes only:
#external .myClassName
Look here for some more information
https://vcfvct.wordpress.com/2013/10/04/disable-obfuscation-in-gwt-css-resources/