简体   繁体   中英

Load SVG's through image tag and be able to change it's color without fetching inline SVG with AJAX?

For the company I work at, I am required to load in SVG's for a web application. The SVG's are in components that consist of HTML code. These components are loaded into a bigger HTML structure. Each component can have a different SVG icon and it must be easy to change. It's color must also be able to be changed through CSS.

I can not write down inline SVG, because administrators must be able to easily change the image (eg: from https://example.com/svg/potato.svg to https://example.com/svg/carrot.svg . I can also not use any AJAX/fetch related functions to fetch the inline SVG, as the component must be able to run perfectly on the test domain, which will trigger CORS errors. Changing the CORS settings is not an option for this application.

My only option left is to load all SVG's (10 at the moment, but could scale anytime) and to look for the right one, depending on the user inputted svg name. I could make the user call a JS function like this: showSVG('carrot'); , but I'd rather not load all SVG's for the sake of loadtime.

Some answers tell you to use CSS filter , but that requires the user to probably look up the correct filters for the correct hex code. I'd just like the user to be able to write the CSS like this: fill: #eee; I also checked out CSS mask , but that has ok-ish support, so I'd rather not use that right now.

Here is an example of what I'd like to achieve:

HTML

<div class="img">
        <img src="https://example.com/svg/carrot.svg" alt="">
        <p>Test component</p>
</div>

CSS

.img {
  fill: yellow; 
}

I'm open for the hackiest Javascript solutions, as long as they are available for every browser.

Modern browsers can do this without JS by making use of the SVG <use> element. However, I recommend using a JS shim like svgxuse , for older browsers, including IE11.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
img {
    border: 2px solid black;
}
svg {
    border: 2px solid goldenrod;
}

svg[class*=fill-] {
    font-size:56px;
    font-weight: bold;
    font-family: Verdana, Helvetica, sans-serif;
    /* When using the <use> element, you need to set the styles in the page, 
    but when loading it as a regular image, styles set within the SVG file will be used. 

    Be careful about using inline styles to set any colors, since those will override others. */
}
svg.fill-blue {
    color: blue;
    fill: currentColor;
}
svg.fill-green {
    color: green;
    fill: currentColor;
}
svg.fill-orange {
    fill: orange; /* the currentColor value trick is optional */
}
</style>
</head>
<body>

<img src="external-svg-example.svg" alt="">

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="720" height="90">
<image xlink:href="external-svg-example.svg" width="720" height="90"/>
</svg>

<!-- It may be desirable to place the xmlns:xlink attribute in the <html> tag instead of each <svg> tag. -->

<!-- Note that IE11 and older and some older versions of other browsers 
do not support loading external SVGs via the <use> element.
JS workarounds do exist, e.g. https://github.com/Keyamoon/svgxuse

More info:
https://stackoverflow.com/questions/22516712/svg-use-tag-with-external-reference-in-ie-11 -->

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="720" height="90" class="fill-blue">
<use xlink:href="external-svg-example.svg#g1"/>
</svg>

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="720" height="90" class="fill-green">
<use xlink:href="external-svg-example.svg#g1"/>
</svg>

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="720" height="90" class="fill-orange">
<use xlink:href="external-svg-example.svg#g1"/>
</svg>

<script src="svgxuse.js" defer></script>
</body>
</html>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 720 90" width="720" height="90">
<style>
svg:root {
    /* "svg:root" is used so this rule won't interfere with other styles when this SVG is injected into a page via JS. */
    color: red;
    fill: currentColor;
    font-size:56px;
    font-weight: bold;
    font-family: Verdana, Helvetica, sans-serif;
}
</style>
<g id="g1">
<text y="70" x="28">This is Our Test Text</text>
</g>
</svg>

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