Native web-components - styling shadow dom - javascript

I have an index.html file that contains css classes. I would like that this classes or at least some of them work in the shadow dom of my component.
I found a way for chrome to use ::part(). With this i can give styles to my Component "share-button" - share-button::part(button) {}
Well. In chrome and opera it works very well but not in firefox (yes, latest version).
Is there a way to ship around for browser who do not support ::part()?
Thank you

One way it to save the CSS that is needed in both the shadowDOM and the regular DOM in a separate CSS file and then load it into the page and into the shadowDOM using the <link> tag.
Another way is to bind the external CSS into the component using a packaging app so it is fully self contained. And then use <link> to get it into the main page.

Related

How to make JS tooltips work in Shadow DOM?

I am using Vue & Bootstrap for an app where I generate web components according to the official Vue documentation (https://cli.vuejs.org/guide/build-targets.html#web-component). For the most part Bootstrap and my business logic is working fine within the #shadow-roots of the web components as if it were in the light DOM.
However, Bootstrap tooltips (which are based on Popper.js https://popper.js.org/) are not working within the Shadow DOM at all. I have also tried to invoke tooltips directly with Popper.js and Tippy.js (https://atomiks.github.io/tippyjs/) in the Shadow DOM encapsulated code, sidestepping Bootstrap altogether, and I still cannot get them to work.
See example here: https://jsfiddle.net/mfep6rg9/
I can guess why -- the 3rd party tooltip libraries most likely aren't finding the target DOM element because it's in a Shadow DOM.
Is there a 3rd party solution out there that accounts for Shadow DOM / web component encapsulation?
Your guess is correct. 3party solutions using document. are not querying shadowDOM.
And there probably is no 3rd party solution as a solution requires either
WebComponents to communicate Mouse positions to the outside world.
Host querying shadowDOM (and nested shadowDOMs and nested shadowDOMs)
Not much different from an (even more restricted) IFRAME
I had the same problem while building LitElement-based Web Components and found the following solution:
$(this.shadowRoot.querySelectorAll("[data-toggle='tooltip']")).tooltip();
Make sure to target the respective element's shadowRoot and run a querySelectorAll to listen to all shadowRoot child elements that listen to "data-toggle='tooltip'".

Shadow DOM- encapsulate JS and CSS files

I have created a component (custom element) that will use specific version of JQuery and Bootstrap libraries. Now I need to add this component into other applications which are already using different version of JQuery and Bootstrap libraries. Some of the applications in which I will add my component is not using bootstrap library and including it may create other issues.
Now to keep the implementation simple, I am planning to use shadow dom. Is it possible to create a element using Shadow DOM which internally use multiple JS and CSS files but when included in other applications, does not cause any issues with respect to JS and CSS files its using.
What I know is shadow DOM does not encapsulate JavaScript. What are my options here ?
Concerning JavaScript libraries, it depends if the library was designed for that.
It's possible with jQuery thanks to its noConflict() mode.
Concerning CSS libraries, they can be included in the Shadow DOM using the #import url rule.
The rule should be placed at the very beginning of the <style> element.

JS Flexbox style CSS class aded to html file

I'm working on a search engine. And I'm having display issues, some features, style like fonts are added to my page. When I look at the elements tab I see things that do not exist in my style tag on my file.
I have another version of this file that works perfectly without any display issues. the only difference between the two files is that each file loads data from a different database. Also the page that i'm having trouble with does not display things like the description that you can see in the second page. Here are screen shots of both:
This is the page with the problems
and this is the page that works fine
You have Modernizr in your website, which adds the classes to the HTML tag. This should however not affect your styles (if you are not specifically targeting it). If your layout actuallay does differ, you probably have different style declarations which are affected by those classes.
Modernizr is a feature detection JavaScript library. It allows to distinct between browsers, which support a feature and such that do not.
See https://modernizr.com/docs

How do frameworks like angular contain css within a component?

More of a curious question rather than solving an actual problem.
How do frameworks like angular contain CSS within a component and prevent the CSS from leaking all over the page?
Angular 2 uses the ShadowDOM concept which allows for CSS to be contained within a component.
By default Angular 2 uses "emulation" which means it emulates a ShadowDOM implementation so that its more likely to work on older browsers.
It can be set to use the native browser implementation (but will only work if the browser supports it).
As a side note, ShadowDOM can be completely turned off in angular 2 and CSS will leak as you expect it.
In default ViewEncapsulation.Emulated CSS is added to <head> for all components. Component tags and the elements in their template get a unique CSS class added and the selectors of the styles are rewritten by Angular2 before they are added to <head> to only match the specific component where the styles were added to.
If ViewEncapsulation.Native is used for browsers with native shadow DOM support, the styles are added directly into the component.
If the browser doesn't have native shadow DOM support and webcomponents polyfills are loaded this works similar as Angular2 with ViewEncapsulation.Emulated

Shadow dom in HTML

I've been hearing about Shadow DOM recently. While watching a video about the release of Angular 2 the presenter repeatedly made mention of Shadow DOM without clear expressions. What does Shadow DOM really mean?
The best explanation I've found is this from What the Heck is Shadow DOM? shown below:
Shadow DOM refers to the ability of the browser to include a subtree
of DOM elements into the rendering of a document, but not into the
main document DOM tree.
An important use case would be with video controls on a web page. The markup only shows a video tag, with some attributes and source tags. The addtional code for all the video operations to work is hidden in the Shadow DOM and not available to the rest of the page. The actual markup, javascript, and styles for the tag are encapsulated, which hides the implementation details of the video controls that each browser vendor has already written.
So while it's there in the DOM, its hidden from the page that renders it. So, to view the Shadow DOM, you can enable it under Dev Tools in Chrome.
The short answer is that the Shadow DOM is one of four technologies that make up Web Components.
For a definition, Web Components are: A component platform from the W3C that allows Web sites to be constructed from standardized building blocks. Web Components comprise Custom Elements, Shadow DOM and HTML Imports and Templates.
Shadow DOM is a technology of Web Components (although each can be used separately):
Custom Elements: is a capability for creating your own custom HTML tags and elements. They can have their own scripted behavior and CSS styling. They are part of Web Components but they can also be used by themselves.
HTML Templates: The HTML template element is a mechanism for holding client-side content that is not to be rendered when a page is loaded but may subsequently be instantiated during runtime using JavaScript. Think of a template as a content fragment that is being stored for subsequent use in the document.
Shadow DOM: provides encapsulation for the JavaScript, CSS, and templating in a Web Component. Shadow DOM makes it so these things remain separate from the DOM of the main document. You can also use Shadow DOM by itself, outside of a web component.
HTML Imports: is intended to be the packaging mechanism for Web Components, but you can also use HTML Imports by itself. You import an HTML file by using a tag in an HTML document.
See Introduction to the Shadow DOM.
It refers to the ability to create a "child" DOM completely sandboxed from the rest of the page. Useful for web components, reusable "widgets" which allow to not worry about their css/js affecting things they shouldn't. http://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/
Check out https://www.polymer-project.org/ if you want to see it in action.
Think of shadow DOM is as an encapsulated (private) DOM.
You can't access the shadow DOM in the manner you access regular DOM, like 'document.querySelector()'.
Let's say, you defined a reusable custom element, (which contains its DOM trees). Then you use the custom element within your app HTML.
Now, the DOM under (which is now called a "host element") has become a shadow DOM subtrees (under a shadow root), hidden from the parent structure!
I hope this help you a bit.

Categories

Resources