Whilst we are waiting for HTML Modules to arrive in all Browsers
(Chrome Platform Status)
The〈load-file〉Web Component
✔️ Fetches any external text file: ie. .txt , .svg , .html
✔️ Injects the content into the DOM
-
in shadowDOM
- respects lightDOM content for shadowDOM
<slot>elements - with optional scoped CSS styling! ✨✨✨
- can move lightDOM content to shadowDOM
- respects lightDOM content for shadowDOM
Or replaces the
<load-file>element itself with thereplaceWithattribute
✔️ is not a replacement for 'HTML Imports'; <script> will not execute
✔️ is done in 7 lines of code:
There are multiple ways to put an external SVG file on the page
source: https://vecta.io/blog/best-way-to-embed-svg
-
👉 as src :
<img src="file.svg">- SVG content can not be styled with CSS
-
👉 as Object :
<object type = "image/svg+xml" data="file.svg"></object>- CORS restrictions apply
-
👉 as CSS background-image
background-image: url(file.svg) -
👉 🎉 use the
<load-file>Web Component 🎉- Loads external files
- provides scoped CSS styling
<load-file replaceWith src="//load-file.github.io/heart.svg"></load-file>
<load-file src="//load-file.github.io/heart.svg">
<style shadowRoot>
path:nth-child(2n+2) {
fill: GREEN; /* shadowDOM style does NOT style global DOM */
}
</style>
</load-file>
- display as bare SVG, by using the
replaceWithattribute- (global) CSS styles all SVGs (see red heart puzzle pieces)
- OR, display contained in shadowDOM
- now (local) CSS styles one SVG (see green heart puzzle pieces)
Loading the <load-file> Web Component
Load the element from the Repo
<script src="https://load-file.github.io/element.js"></script>
It doesn't matter when the Custom Element is loaded/defined.
Any existing <load-file> elements in the document will automagically upgrade when the Custom Element is defined later.
or define the entire element in the <head> of your HTML document with a <script> tag:
<script>
customElements.define("load-file",class extends HTMLElement{async connectedCallback(){
this.shadowRoot||this.attachShadow({mode:"open"});this.shadowRoot.innerHTML=await(
await fetch(this.getAttribute("src"))).text();this.shadowRoot.append(...this.children);
this.hasAttribute("replaceWith")&&this.replaceWith(...this.shadowRoot.children)}})
</script>
Using the <load-file> Web Component
Specify the full path in the src attribute
add the replaceWith attribute so the src content replaces the <load-file> Element itself in the document
<load-file replaceWith src="https://load-file.github.io/heart.svg"></load-file>
!! Note the CAPITAL in replaceWith (creates a better GZip compressed file)
Without replaceWith the source content will be injected in shadowDOM:
<load-file src="https://load-file.github.io/heart.svg"></load-file>
All elements with attribute shadowRoot are moved to shadowDOM:
<load-file src="https://load-file.github.io/heart.svg">
<style shadowRoot>
path:nth-child(2n+2) {
fill: GREEN; /* shadowDOM style will NOT style global DOM */
}
</style>
</load-file>
Top comments (3)
Pretty cool, I like it :D
However, you forgot to mention SVG can be loaded with
<object>, which allows some more of the CSS inside the SVG to do its magic, outside style rules still don't apply, but if I remember correctly, outside custom properties are available inside the SVG.Tnx,
I added
objectand a link to vecta.io/blog/best-way-to-embed-svg which describes all in detailAlso changed functionality slightly. Only the first
<style>element will now be moved to shadowDOM. That way any<slot>element in a loaded .html file will slot content from lightDOM correctlyThanks for the list. I've learned two cool new ways to add external content to the DOM. However, I'm not convinced on using the object tag for loading an svg. Rarely does one use SVG on a web page without having to adjust the styling. But you can't selectively style the svg inside the external object tag. And if you have to change the styles inside the SVG itself, that makes the SVG file less versatile.
In the end, I used CSS mask with the
mask-imageproperty pointing to the SVG.However, for embedding content that you don't intend to change, like a pdf, or video, the object tag is a great method.