grunt-svgstore icon indicating copy to clipboard operation
grunt-svgstore copied to clipboard

Cross-icon gradient use

Open samdbeckham opened this issue 10 years ago • 3 comments

I'm having an issue with sharing gradients across icons. This circle will work:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%" stop-color="#009fe3" />
    <stop offset="100%" stop-color="#662483" />
    </linearGradient>
    <circle cx="50" cy="50" r="75" fill="url(#grad1)"/>
</svg>

But then I can't reference that same gradient later, eg:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
      <rect width="75" height="75" fill="url(#grad1)" />
</svg>

It seems to be because of the way SVG store handles the ids. It prepends the file hash on to the beginning of the ids to make it unique (which it rightly should) but this change doesn't seem to permeate through the rest of the file. so you end up with a sprite like this:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" class="hide">
    <defs>
        <linearGradient id="[hash]grad1" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0%" stop-color="#009fe3"/>
            <stop offset="100%" stop-color="#662483"/>
        </linearGradient>
    </defs>
    <symbol viewBox="0 0 100 100" id="icon__circle">
        <title>circle</title>
        <circle cx="50" cy="50" r="75" fill="url(#[hash]grad1)" />
    </symbol>
    <symbol viewBox="0 0 100 100" id="icon__rectangle">
        <title>rectangle</title>
        <rect width="75" height="75" fill="url(#grad1)" />
    </symbol>
</svg>

Everything would work fine if the reference to the gradient in the second (rectangle) icon was updated to use the hashed id. Alternatively, if there was a way to preserve the ID that would be even better. It would allow you to write the following CSS:

.icon__grad-1{
    fill: url(#grad1);
}

Obviously I would use a more specific ID in production code, but you get the idea.

samdbeckham avatar Dec 02 '14 17:12 samdbeckham

Pre-defining the defs could be a good way around this too. If I could define the following in a separate file (without the ids being modified), that would be pretty nice:

<defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
        <stop offset="0%" stop-color="#009fe3"/>
        <stop offset="100%" stop-color="#662483"/>
    </linearGradient>
</defs>

samdbeckham avatar Dec 02 '14 17:12 samdbeckham

The philosophy of grunt-svgstore is to take a folder of existing (valid and complete) svg icons and concatenate them to a "svgsprite". I don't like the idea of breaking that because it would introduce much more complexity to this task.

But I like your idea with using a separate svg that gets merged into the resulting svg. If you have time implementing it I am open for a PR (I don't have time to do that myself)

FWeinb avatar Dec 15 '14 17:12 FWeinb

That's a good point, no use breaking the philosophy for one edge-case. Having the gradient as an extra SVG should still adhere to that philosophy though so I'll look at making a PR soon.

samdbeckham avatar Dec 16 '14 10:12 samdbeckham