Mitkins
Mitkins

Reputation: 4341

Svg sprites with copy and paste support

The following Emojione demo suggests adding the description tag to allow the user to copy and paste the original unicode character:

https://demos.emojione.com/latest/sprites-svg.html

However, on macOS (at least) I am unable to copy and paste the whale (on the page).

Here's a variation of the sample code that I tried on my site:

<svg class="emojione">
  <description>&#x1f433;</description>
  <use xlink:href="/images/emojione.sprites.svg#emoji-1f433"></use>
</svg>

I tried doing the same thing using an img tag:

<img alt="&#x1f433;" src="/images/emojione.sprites.svg#emoji-1f433" />

However, the image shows up blank.

Upvotes: 0

Views: 366

Answers (2)

12Me21
12Me21

Reputation: 1169

<description> isn't a valid SVG tag, it's just treated as an unknown element.

I believe the correct solution here would be to use an invisible <text> element (but perhaps there's a better way)

.sprite {
  height: 20px;
  vertical-align: top;
}

.sprite text {
  fill: transparent;
  font-size: 1px;
  dominant-baseline: text-before-edge;
}
<fieldset>
Try copying
<svg viewBox=0,0,1,1 class='sprite'>
    <text>🔴</text>
    <use href=#red_circle />
</svg>
this text.
<br>
</fieldset>
<input placeholder="paste here">

<svg style=display:none>
    <symbol id=red_circle viewBox=-4,-4,8,8 width=100% height=100%>
        <circle r=4 filter=url(#ball) />
        <filter id=ball>
            <feSpecularLighting specularExponent=20 lighting-color=red>
                <fePointLight x=-2 y=-1 z=8 />
            </feSpecularLighting>
            <feComposite in=SourceGraphic operator=lighter />
        </filter>
    </symbol>
</svg>

Upvotes: 0

Mitkins
Mitkins

Reputation: 4341

Seems like the best cross-browser solution to display an svg image so it can be copied and pasted is via an <img> tag.

According to this explanation, the <symbol> tag in the sprite file is not rendered unless it is referenced by the <use> clause.

I'm assuming that's why the Emojione icons don't show up - the src attribute doesn't have a <use> clause, so the referenced <symbol> tag is never rendered. Mind you, I did try embedding the inline svg (above) in the src attribute of the <img> tag, like so:

<img src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICA8ZGVzY3JpcHRpb24+JiN4MWY0MzM7PC9kZXNjcmlwdGlvbj4NCiAgPHVzZSB4bGluazpocmVmPSIvc3ByaXRlcy9lbW9qaW9uZS5zdmcjZW1vamktMWY0MzMiPjwvdXNlPg0KPC9zdmc+" />

But that didn't work.

The next best solution was to use <g> tags in the sprite file instead. Similar to this:

<?xml version="1.0"?>
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<defs>
    <style><![CDATA[
        .sprite { display: none; }
        .sprite:target { display: inline; }
    ]]></style>
</defs>

<g class="sprite" id="circle">
    <ellipse cy="50" cx="50" ry="45" rx="45" stroke-width="5" stroke="#00ff00" fill="#00ff00" fill-opacity="0.75" />
</g>

<g class="sprite" id="square">
    <rect y="5" x="5" width="90" height="90" stroke-width="5" stroke="#ff0000" fill="#ff0000" fill-opacity="0.75" />
</g>

<g class="sprite" id="triangle">
    <path d="M20,7 L92,50 L6,93 z" stroke-width="5" stroke="#0000ff" fill="#0000ff" fill-opacity="0.75" />
</g>

</svg>

(which comes from the following tutorial).

However, this is where Safari becomes a pain. This is the result of Chris Coyier's demo from the following CSS Tricks post:

enter image description here

Anything that involves a fragment reference (in the above image) does not work in Safari 10.1. If I choose an option that works with Safari, things start to get inconvenient and I'd have to do more testing across browsers/devices to ensure that the solution is going to work.

Bear Travis has some workarounds for Safari, but all of them side-step the <img> tag.

For now, I'll stick with using separate svg files (rather than a single svg sprite).

Which is a shame.

Here's an awesome article from Sara Soueidan on sprite creation techniques. It's comprehensive and made me wish that I could just use an inline <svg> tag with copy and paste support.

Upvotes: 0

Related Questions