简体   繁体   中英

Display svg as image from external url

I have a Firebase storage bucket with svg files in it. The urls for each file are stored in Firestore. I am fetching the urls from firestore so I can display the svgs as images in html. I am using vanilla HTML, CSS, and JS and using UIKit for layout.

What I mean by "display the svgs as images" is:

  • I want the user to be able to right click, and click "Save image as".
  • I do NOT want my CSS to affect the svgs in any way.
  • I do not need to manipulate the SVGs programmatically.

I am using UIKit and have tried both of their documented methods of displaying svgs:

Method 1: as an inline svg image

var source = logo.imageURL;

var div = document.createElement("div");
var img = document.createElement("img");
img.width = 160;
img.src = source;
img.setAttribute("uk-svg", "");
div.appendChild(img)
parent.appendChild(div);

This results in the ability to see the svgs on the page, but:

  • You can't right click them to save them
  • UIKit's CSS is affecting the colors (all fills are gray).

Method 2: lazy loading using Image component

var source = logo.imageURL;

var div = document.createElement("div");
var img = document.createElement("img");
img.width = 160;
img.src = source;
img.setAttribute("uk-img", "data-src:" + source);
img.setAttribute("uk-svg", "");
div.appendChild(img)
parent.appendChild(div);

This results in the svgs showing up as blank white squares.

Other tests I have done:

I grabbed one of the svg files and added it to my frontend /images folder and hardcoded the source variable to use the local file. The SVGs showed up fine, and met all my criteria above, so I assume there's nothing wrong with the file itself.

Any help or advice with this would be great.

With vanilla HTML5, if your want CSS isolation you need to place it in shadowDOM (supported in all modern browsers)

Either attach shadowDOM to your own <span> element;

Or take it one step further and create your own re-usable HTML Element <shadow-svg> (or any name you want)

Note: the SVG being an IMG src should be enough to not be affected by global CSS; so shadowDOM not strictly required. It ensures the IMG can not be styled by global CSS in this example.

 <span id=SVG></span> <shadow-svg src="https://svgshare.com/i/U7z.svg"></shadow-svg> <shadow-svg src="https://svgshare.com/i/U7o.svg"></shadow-svg> <shadow-svg src="https://svgshare.com/i/U7p.svg"></shadow-svg> <style> #SVG { height: 130px; background: pink } </style> <script> SVG.attachShadow({ mode: "open" }).innerHTML = `<style>:host{display:inline-block}img{height:130px;width:130px}</style>` + `<img src="https://svgshare.com/i/U7L.svg">`; // OR customElements.define("shadow-svg", class extends HTMLElement { constructor() { super().attachShadow({ mode: "open" }).innerHTML = `<style>:host{display:inline-block}img{height:130px;width:130px}</style>` + `<img src="${this.getAttribute("src")}">`; } }); </script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM