add react component to existing webpage and avoid CSS conflicts - html

I'm developing a React/MaterialUI component that will be embedded in existing websites.
In order to minimise the work needed on the existing page to embed my component, I'm bundling my component into an app.js and the only change requested to the existing page is something like:
<div id="embedded-component"></div>
<script type="text/javascript" src="https://example.com/app.js"></script>
my component finds the div by ID and then mounts on that element.
Things are mostly working but I'm having issues with CSS conflicts between the CSS files on the original page (which I can't modify) and the elements of my application.
For example the original page uses text input elements with a border/padding/color that I don't want my component to "inherit".
I want my component to display the same way regardless of which page is embedded on.
Is there any strategy/tool to use in this case, so CSS classes on existing page do not affect the elements of my embedded component?
Trying to find a solution to this I've come across the Shadow DOM (e.g. https://medium.com/rate-engineering/winning-the-war-of-css-conflicts-through-the-shadow-dom-de6c797b5cba) but I'm not sure how widely supported this is in different browsers.
Is there any solution to this, that is widely supported by all major browsers?
I cannot use iframes and have full control of my js/css files but no control over the existing page other than the "mounting" div.

Related

On page load, display static images at the same time vue dynamically loaded images

On my working project, the frontend is not entirely an SPA, as well not defining all the components in the template engine, but image loading is inconsistent between the document and vue. I am having trouble coming up with an appropriate solution with loading the document images when the vue components are loading and displaying.
We need to display everything at once when vue displays components.
One solution I can think of is to apply the source links in data-src in all the img elements. When vue is ready to display the components, the value from data-src would be applied to the src attribute and the browser starts to download the image files.
But there are other issues with CSS loading images as well and I'm not sure how I would control the loading there. I'm assuming I would have to define outside of CSS and use JS for this?
2 other solutions I can think of is to just hide the page until vue has completed rendering, but this would increase the time to see the page. Or use placeholder media in place of loading photos.

Dynamic Theming Ionic Issue

I'm using Ionic with Angular to develop an App. I intruduced dynamic theming adding two .scss files into my theme folder. I've got app.scss where I define only the layout of my components without colors. All colors are in the theme-*.scss files. To apply a theme I use a class over <ion-nav> element into my app.html. Something like this:
<div [class]="selectedTheme">
<ion-nav [root]="rootPage" ></ion-nav>
</div>
The selectedTheme is a string that assume the name of my theme so when I change it with an event such (click) or (ionChange) I can change the colours of my app.
A file theme-*.scss has the following structure:
.dark-theme {
ion-header {
//colors
}
ion-content {
//colors
}
}
This way works like a charm, but I've got a little issue I want to avoid. I set the default theme in constructor of app-components.ts file, before the famous platform.ready().then(...) that hides the splashscreen. My issue is that when the splashscreen hides I can see my app with its layout but without the correct theme applied. I see all white backgrounds and all black colors for a small amount of time, then the default theme is applied. I'm importing my custom themes in variables.scss, I tried to import them also in app.scss but the behaviour remain the same. It seem that before import the themes it applies the layout in app.scss and only after it applies the imported theme with all its colours. Someone has already see something like this?
I think that your issue is caused by timing of first paint which is an attribute on browsers. The webview where ionic runs can be consider as a sort of browser. So, same issue occurs.
why-first-paint-is-happening-before-domcontentloaded is a great explanation related to your question.
This page talks about first paint can start before DOM is fully loaded.
Especially, the below cited paragraph from the link describes same phenomenon of your app.
E.g. the parser obviously cannot emit Element nodes before processing
all of its attributes, but it can emit the node while still processing
its child tree. And the renderer may render the node without its
children. And it may be rendered with incomplete styles only to
undergo a reflow later, e.g. when javascript inserts another style
sheet or simply because the child nodes which have yet to be inserted
affect how it will be rendered.
In conclusion, you can not guarantee DOM is loaded before painting. So, I think that practical solution is hiding your splash screen a little bit later.

add style to html without angularjs loading them

I am using ui-router of angularjs in my SPA. When i add an style to my view pages, angularjs loads them when switching to than view. Thats actually pretty cool that it can be done in runtime.
The problem is i do not want it to do so. for example i want to use bootstrap css in my view. it is already inserted in the main page, so it is not needed to get loaded again form child view. but for my IDE to auto-complete class names, it is needed to be added to html page of subview.
Is there any way to ask Angularjs to ignore Head part and just load Body part of my html?

applying styles to static site html and user generated html content

We are using twitter bootstrap to do some redesign of our site.
The issue we have is that the part of the site we are redesigning is that this part shows content that the user is able to enter themselves including html tags .eg etc that they may have defined their own styles for.
The problem with this is that the bootstrap stylesheet would overwrite the user stylesheet or vice versa.
Is there a way to scope the stylesheet to a particular class (ie twitter stylesheet only applies to elements inside a div with class = "twitter" or something similar) without it affecting the user stylesheet and without having to modify all of the twitter classes to include a more specific selector.
We have considered using an iframe but we really need good control over the user content to be able to send/receive from it pretty easily, ie. ajax methods that trigger things on the rest of the page
Using an iframe is the way to go.
Here's some examples of how to communicate with it and access it's content.
The iframe content can call a function in the parent like this:
parent.yourFunction()
The parent can call a function in the iframe like this:
document.getElementById('iframeid').contentWindow.yourFunction();
The parent can access the iframe's html like this:
document.getElementById('iframeid').innerHTML() = "<html><body><div>some content</div></body></html>";
Not quite what you were hoping but it's the only way to have css only apply to part of a page.

Can I display an inner div with an independent stylesheet?

My application lets users edit documents. The editor widget, unsurprisingly, represents user documents as HTML.
I need to redisplay the documents outside the editor, but inside my site's layout. Documents need to appear in the exact same style they are presented in the editor, unaffected by my site's stylesheet. I could use the editor in read only mode, with all its buttons hidden, but I still will have scrollbar and border style issues to resolve.
I have identified the CSS file that the editor uses. How can I effectively configure a div element (the one that will contain the document) to (1) disregard all current styling, and (2) load a css file to apply to its content?
You have two options:
1.) Reset all styles on the div containing your document, and make sure your document's styles are prioritized over the reset. This could get messy.
2.) Use an iframe and load the document and styles inside the iframe.
<iframe src=".../documents/myDocument.html"></iframe>
Where "myDocument.html" is an html document containing the document and styles (treat the document html page as any other html page, and make sure it has proper head and body tags, etc.
Other options:
1.) Open the document html page inside another window.
<a href=".../document/myDocument.html" target="_blank" >Open Document</a>
2.) Render the document as a pdf, and load it into the page using a pdf viewer. (you would want to keep a backup of the original document, as the conversion back would be terrible, I presume).
Yes and no. If you want to use a div, you will want to use a stylesheet with styles defined to "reset" the css for that div. That would basically undo your site's styles, and then any new style selectors should be limited to within that div itself.
Otherwise, I would suggest using something like an iframe where you can render a truly independent document.