How to prevent styles leaking from v-html in vue - css

I have a vue component that renders multiple child components and a div with v-html directive. The div renders a dynamic HTML source. Sometimes, the styles from the HTML source leak outside the div and affect the other components.
How to prevent this?
Thanks in advance!

Related

Is there a way of overriding the CSS of a Vue component which has been loaded in the browser

I am looking to know if there's a way to override the CSS of a Vue component which has been loaded in the browser.
The component is being worked on by a different developer and is being pushed live independently of the parts of the page I'm working on.
I've tried the following:
using the !important tag
trying to increase css specificity
using the :host() & :root() selectors to try and override the component css
However none appear to work and it appears that the component also generates a style="" in the tags so the CSS is embedded at that level within each tag.
Just wondering is there any way of applying CSS in the base HTML file that would override the CSS of the component.
Thanks for any help with this.

VueJS - add css style with v-html

I would like to add html content from the database (so that a part of the page content can be changed externally).
How to add SCSS styling? I use v-html like this but I ahve no idea how to add the style:
<div v-html="ct"></div>
async created() {
this.ct = await this.getPage("blabla");
}
I would prefer not to add the SCSS part in the vuejs style and I already have some other CSS for the other part of the code, but if necessary, the style could be defined in these assets
<style lang="scss" scoped>
#import '~assets/styles/core';
</style>
I found some answers but it doesn't seem like the style comes from another source
Vue.js style v-html with scoped css
or
Add CSS style to v-html
When using scoped CSS, Vue creates dynamically generated selectors to reference elements. However, v-html content does not get dynamically generated selectors, because Vue is not dynamically creating that HTML, but instead just dumping it in. Therefore, if you're using v-html, scoped styles defined within the parent component(s) will not be applied to the child components without the use of deep selectors.
You either need to keep your styles global, import your stylesheet via your Webpack config so that the classnames aren't altered by Vue to match the Vue instances' dynamic selectors, or take the styles specific to the v-html child elements and rewrite them to use deep selectors.

How to prevent vue package styles to be applied to parent page

I created a simple vue component that is loaded from a normal web page which contains own styles.
Using any type of vue frontend framework like vue-bootstrap or fish-ui those styles get applied to the whole page, which ends up in crashing the parent pages styles, because the included styles also have base element styles like body or `::selection, etc.
What is the way to prevent this?
I also realized that the parent pages css applies to the bootstrap / fish-ui components. For instance: <fish-input label="xxlabel"/> creates a <label> component which is affected because it does not get a data-id.

Angular: Component styles do not cascade to sub-components?

In my app.component.html I have the following, working class assignment.
<body>
<span class="test">SHABOO</span>
<div class="container">
<router-outlet></router-outlet>
</div>
</body>
In the outlet, a component is rendered and it contains the following.
<span class="test">HAZAA</span>
I expected it to get the same style as the first one but it seems that the style doesn't cascade down to the component. It made me uncertain if I'm mistaken about how the styles are supposed to behave between parent and child components in Angular.
I made sure that the name of the class isn't overriden (to exclude the risk of collision). At the moment, I'm putting similar chunks of SCSS code in each component and that's obviously bad practice.
If I #import "../app.component.scss", the styles kicks in. But I was under the impression that even without the import, the style is supposed to cascade.
Angular components use view encapsulation. This is by design so that components are reusable across applications. To treat a component's styles as global, set the view encapsulation mode to none (not recommended).
Instead of using none, register global style files in the Angular CLI styles section, which is pre-configured with the styles.css file.
Component CSS styles are encapsulated into the component's view and don't affect the rest of the application.
To control how this encapsulation happens on a per component basis, you can set the view encapsulation mode in the component metadata. Choose from the following modes:
ShadowDom view encapsulation uses the browser's native shadow DOM implementation (see Shadow DOM on the MDN site) to attach a shadow DOM to the component's host element, and then puts the component view inside that shadow DOM. The component's styles are included within the shadow DOM.
Native view encapsulation uses a now deprecated version of the browser's native shadow DOM implementation - learn about the changes.
Emulated view encapsulation (the default) emulates the behavior of shadow DOM by preprocessing (and renaming) the CSS code to effectively scope the CSS to the component's view. For details, see Appendix 1.
None means that Angular does no view encapsulation. Angular adds the CSS to the global styles. The scoping rules, isolations, and protections discussed earlier don't apply. This is essentially the same as pasting the component's styles into the HTML.
To set the components encapsulation mode, use the encapsulation property in the component metadata:
src/app/quest-summary.component.ts
// warning: few browsers support shadow DOM encapsulation at this time
encapsulation: ViewEncapsulation.Native
ShadowDom view encapsulation only works on browsers that have native support for shadow DOM (see Shadow DOM v1 on the Can I use site). The support is still limited, which is why Emulated view encapsulation is the default mode and recommended in most cases.
External and global style files
When building with the CLI, you must configure the angular.json to include all external assets, including external style files.
Register global style files in the styles section which, by default, is pre-configured with the global styles.css file.
See the CLI wiki to learn more.
This is how angular works. Every component is separated with it's CSS, even if it is child component of a parent. They can't inherit their parent CSS.
Haza span component is child of your app component, but it is separated component. So, you can't get those Shaboo styling to Haza.
Solution:
if you want to maintain same CSS, there are multiple ways.
Recommended way:
a) if it is only for onle class, copy the class to the child component.
b) if it is for huge number of classes, create a css file for them and import them in both parent and child component css.
Example:
#import '../span.css';
you can add this css to styles.css. then you will get it anywhere in the app. if you want this style many places, you can do it.
As #Christopher Peisert mentioned, by using
encapsulation: ViewEncapsulation.Native
end of the #component decorator in child.component.ts. It is not recommended way
The global CSS files are those that are listed in angular.json. All others CSS files are encapsulated by default (this can be removed but is not recommended.)
Keeping your global CSS organised is important as your application grows. What I like to do is create a global styles folder and then add new files for different widgets that I might be altering. Since removal of ::ng-deep these types of changes have to be done in the global scope.
It works like that. If you are in need of having a common style then add it in the global styles.scss file.
If you want a global style put it in the global file styles.css or styles.[Your css preprocessor]
See this example https://stackblitz.com/edit/angular-a5ntm6?file=src%2Fstyles.css
I put test class at the end
.test{
color:red;
}

CSS styles not working on already existing component/body tag

I have a project in angular 7, I am loading a component dynamically using routes, in dynamically loaded component style-sheet I am adding some styles for body tag and already existing component tags and they're not reflecting in DOM.
body {
padding-bottom: 150px;
}
Styles are coming in the dynamically loaded component style-sheet, but I don't see them applying on DOM elements.
By default angular only applies the styles within a component, only to HTML elements within that components template (view encapsulation). To override this behaviour you can set an option in the components directive.
For more info see https://angular.io/guide/component-styles#view-encapsulation
If you're defining styles within a component they will not apply outside of the component.
Check out my StackBlitz template.
My global styles are defined in a scss/ folder to apply all global styles downwards into the DOM.
Component styles are then only used to override global styles or for component specific styles used no where else in my project.
This is how I set up my Angular styles. Let me know if you need more help.

Resources