Can I re-use the same SVG in a page and apply diff

2019-04-18 07:35发布

I have an SVG file that I want to use in a web page. I want the image to appear multiple times, but to apply different CSS styles to each one.

Is this possible?

Clarification

When I say "apply different CSS styles", I mean that I want to style the SVG contents (stroke, color, radius, etc), not just the width of an <img> or something.

Also, I don't consider "copy and paste the SVG contents" to be "re-using" it. I want to create a file like logo.svg and reference it from the HTML.

标签: html css svg
4条回答
何必那么认真
2楼-- · 2019-04-18 07:48

Demo

html

<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 65.326 612 502.174" enable-background="new 0 65.326 612 502.174" xml:space="preserve" class="logo">
    <path class="kiwi" d="M210.333,65.331C104.367,66.105-12.349,150.637,1.056,276.449c4.303,40.393,18.533,63.704,52.171,79.03
  c36.307,16.544,57.022,54.556,50.406,112.954c-9.935,4.88-17.405,11.031-19.132,20.015c7.531-0.17,14.943-0.312,22.59,4.341
  c20.333,12.375,31.296,27.363,42.979,51.72c1.714,3.572,8.192,2.849,8.312-3.078c0.17-8.467-1.856-17.454-5.226-26.933
  c-2.955-8.313,3.059-7.985,6.917-6.106c6.399,3.115,16.334,9.43,30.39,13.098c5.392,1.407,5.995-3.877,5.224-6.991
  c-1.864-7.522-11.009-10.862-24.519-19.229c-4.82-2.984-0.927-9.736,5.168-8.351l20.234,2.415c3.359,0.763,4.555-6.114,0.882-7.875
  c-14.198-6.804-28.897-10.098-53.864-7.799c-11.617-29.265-29.811-61.617-15.674-81.681c12.639-17.938,31.216-20.74,39.147,43.489
  c-5.002,3.107-11.215,5.031-11.332,13.024c7.201-2.845,11.207-1.399,14.791,0c17.912,6.998,35.462,21.826,52.982,37.309
  c3.739,3.303,8.413-1.718,6.991-6.034c-2.138-6.494-8.053-10.659-14.791-20.016c-3.239-4.495,5.03-7.045,10.886-6.876
  c13.849,0.396,22.886,8.268,35.177,11.218c4.483,1.076,9.741-1.964,6.917-6.917c-3.472-6.085-13.015-9.124-19.18-13.413
  c-4.357-3.029-3.025-7.132,2.697-6.602c3.905,0.361,8.478,2.271,13.908,1.767c9.946-0.925,7.717-7.169-0.883-9.566
  c-19.036-5.304-39.891-6.311-61.665-5.225c-43.837-8.358-31.554-84.887,0-90.363c29.571-5.132,62.966-13.339,99.928-32.156
  c32.668-5.429,64.835-12.446,92.939-33.85c48.106-14.469,111.903,16.113,204.241,149.695c3.926,5.681,15.819,9.94,9.524-6.351
  c-15.893-41.125-68.176-93.328-92.13-132.085c-24.581-39.774-14.34-61.243-39.957-91.247
  c-21.326-24.978-47.502-25.803-77.339-17.365c-23.461,6.634-39.234-7.117-52.98-31.273C318.42,87.525,265.838,64.927,210.333,65.331
  z M445.731,203.01c6.12,0,11.112,4.919,11.112,11.038c0,6.119-4.994,11.111-11.112,11.111s-11.038-4.994-11.038-11.111
  C434.693,207.929,439.613,203.01,445.731,203.01z" />
</svg>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 65.326 612 502.174" enable-background="new 0 65.326 612 502.174" xml:space="preserve" class="logo">
    <path class="kiwi" d="M210.333,65.331C104.367,66.105-12.349,150.637,1.056,276.449c4.303,40.393,18.533,63.704,52.171,79.03
  c36.307,16.544,57.022,54.556,50.406,112.954c-9.935,4.88-17.405,11.031-19.132,20.015c7.531-0.17,14.943-0.312,22.59,4.341
  c20.333,12.375,31.296,27.363,42.979,51.72c1.714,3.572,8.192,2.849,8.312-3.078c0.17-8.467-1.856-17.454-5.226-26.933
  c-2.955-8.313,3.059-7.985,6.917-6.106c6.399,3.115,16.334,9.43,30.39,13.098c5.392,1.407,5.995-3.877,5.224-6.991
  c-1.864-7.522-11.009-10.862-24.519-19.229c-4.82-2.984-0.927-9.736,5.168-8.351l20.234,2.415c3.359,0.763,4.555-6.114,0.882-7.875
  c-14.198-6.804-28.897-10.098-53.864-7.799c-11.617-29.265-29.811-61.617-15.674-81.681c12.639-17.938,31.216-20.74,39.147,43.489
  c-5.002,3.107-11.215,5.031-11.332,13.024c7.201-2.845,11.207-1.399,14.791,0c17.912,6.998,35.462,21.826,52.982,37.309
  c3.739,3.303,8.413-1.718,6.991-6.034c-2.138-6.494-8.053-10.659-14.791-20.016c-3.239-4.495,5.03-7.045,10.886-6.876
  c13.849,0.396,22.886,8.268,35.177,11.218c4.483,1.076,9.741-1.964,6.917-6.917c-3.472-6.085-13.015-9.124-19.18-13.413
  c-4.357-3.029-3.025-7.132,2.697-6.602c3.905,0.361,8.478,2.271,13.908,1.767c9.946-0.925,7.717-7.169-0.883-9.566
  c-19.036-5.304-39.891-6.311-61.665-5.225c-43.837-8.358-31.554-84.887,0-90.363c29.571-5.132,62.966-13.339,99.928-32.156
  c32.668-5.429,64.835-12.446,92.939-33.85c48.106-14.469,111.903,16.113,204.241,149.695c3.926,5.681,15.819,9.94,9.524-6.351
  c-15.893-41.125-68.176-93.328-92.13-132.085c-24.581-39.774-14.34-61.243-39.957-91.247
  c-21.326-24.978-47.502-25.803-77.339-17.365c-23.461,6.634-39.234-7.117-52.98-31.273C318.42,87.525,265.838,64.927,210.333,65.331
  z M445.731,203.01c6.12,0,11.112,4.919,11.112,11.038c0,6.119-4.994,11.111-11.112,11.111s-11.038-4.994-11.038-11.111
  C434.693,207.929,439.613,203.01,445.731,203.01z" />
</svg>

css

#Layer_1 {
  width: 200px;
}
#Layer_2 {
  width: 100px;
}
body {
  padding: 20px;
}

You can use it this way if you don't want to use the whole values of svg multiple times.

Demo

html

<img class="papa" src="http://s.cdpn.io/3/kiwi.svg">   
<img class="mama"  src="http://s.cdpn.io/3/kiwi.svg">   
<img class="baby"  src="http://s.cdpn.io/3/kiwi.svg">

css

.papa {
  width: 250px;
}

.mama {
  width: 100px; 
}

.baby {
  width: 50px; 
}

source : http://css-tricks.com/using-svg/

查看更多
3楼-- · 2019-04-18 07:55

No, not currently

Styling the contents (stroke, fill, etc) of an SVG from a containing HTML document is currently not supported.

@RobertLongson was kind enough to point me to the SVG Parameters spec, which could provide a partial solution. It is not implemented in any browser, but can be used with a Javascript shim. However, when I emailed the SVG working group with a question about it, I was told:

The SVG Parameters doc is currently out-of-date. The plan at the moment is to integrate it with CSS Custom Properties and var(); the spec will then become an alternative way to define a custom property.

And

SVG <img>s are actually in a separate document entirely; it's basically the same as an <iframe>, just locked down more strictly. We don't allow direct selection across document boundaries for a combination of security, sanity, and performance reasons.

That said, it seems reasonable for the Parameters spec to define a way to take values from the referencing environment, so you'd set the property on the <img> itself and it would transfer through to the contained document at the document's request.

A non-spec-compliant hack: the use tag

For the record, the following seemed to accomplish my stated goals (technique borrowed from CSS-Tricks), but @RobertLongson let me know that it only worked in Firefox (I think I was using version 31) because Firefox was not compliant with the spec.

<!DOCTYPE html>
<html>
  <head>
    <title>SVG Reuse Demo</title>
    <meta charset="UTF-8" />
    <meta http-equiv="Content-Type" content="text/html" />
    <style type="text/css">
      .circle   .uno { stroke: orange; stroke-width: 5px; }
      .circle-1 .uno { fill: blue; }
      .circle-2 .uno { fill: red; }
      .circle-3 .uno { fill: green; }
    </style>
  </head>
  <body>
    <!-- Single definition of SVG -->
    <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
      <symbol id="disc" viewbox="0 0 100 100">
        <circle class="uno" cx="50" cy="50" r="40">
      </symbol>
    </svg>
    <!-- Re-use; each is styled differently (see above) -->
    <svg class="circle circle-1">
      <use xlink:href="#disc">
    </svg>
    <svg class="circle circle-2">
      <use xlink:href="#disc">
    </svg>
    <svg class="circle circle-3">
      <use xlink:href="#disc">
    </svg>
  </body>
</html>

Even if it were standard, this technique would be less than ideal; the ideal solution would allow using an SVG defined in an external file, like circles.svg.

This is because:

  1. It is clutter to paste it into the HTML (my actual use case may be 300 lines of SVG)
  2. If it were a separate file, I could re-use it in other HTML documents
  3. I could edit it with SVG-specific syntax highlighting
  4. It could be requested and cached separately from the HTML document
  5. ... basically all the other reasons we normally put CSS and images in separate files instead of inline in HTML. :)
查看更多
我只想做你的唯一
4楼-- · 2019-04-18 07:56

Yes, it can be easily done using SVG injection, and it should work on all Browsers that support SVG.

With SVGInject your HTML may look like this:

<html>
<head>
  <script src="svg-inject.min.js"></script>
  <style>
    .redImage {
      /* Your CSS for the red image here */
    }

    .greenImage {
      /* Your CSS for the green image here */
    }
  <style>
</head>
<body>
  <img class="redImage" src="image.svg" onload="SVGInject(this)" />
  <img class="greenImage" src="image.svg" onload="SVGInject(this)" />
</body>
</html>

The onload="SVGInject(this)" triggers the injection after the SVG is loaded and replaces the <img> element with the SVG markup from the specified SVG file.

查看更多
SAY GOODBYE
5楼-- · 2019-04-18 08:00

Yes, absolutely!

If each occurrence is unique, simply apply an id attribute to the svg then reference it and its children with the id prefixing any selectors, e.g

<svg id='myimage ... />

Then in your css:

#myimage line{...}

Would for example apply styles to the line elements within the myimage svg.

I'd also recommend having a look at the MDN article on CSS selectors

查看更多
登录 后发表回答