angular-svg-icon icon indicating copy to clipboard operation
angular-svg-icon copied to clipboard

Replace ids with unique ids

Open DejayJD opened this issue 5 years ago • 5 comments

Problem: Trying to load an svg in multiple components, then change the color in one components, but not have it affect the other svg. Inside of the svg, the color is in a <linearGradient> tag and uses a url(#ID).

When I modify the color using CSS inside of a component (Ex. svg path { fill: white }), every instance of that SVG is changed instead of the specific icon in that component that the css applies to.

Proposed Solution: Give the option to scope the SVG somehow, and potentially load numerous copies. In order to avoid id overlap in this solution, string-replace/append each id with a unique scope id.

Example SVG that I am using (see "#csv-a" for the id I am referring to):

csv.svg

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
    <defs>
        <linearGradient id="csv-a" x1="50%" x2="50%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#21A366"/>
            <stop offset="100%" stop-color="#185C37"/>
        </linearGradient>
    </defs>
    <g fill="none" fill-rule="evenodd">
        <g fill-rule="nonzero">
            <path id="background" fill="#636567" d="M8.667 2A1.902 1.902 0 0 0 6.77 3.905l-.01 15.238c0 1.047.849 1.905 1.896 1.905h11.438A1.91 1.91 0 0 0 22 19.143V8.505c0-.505-.2-.99-.562-1.343l-4.6-4.6A1.872 1.872 0 0 0 15.495 2H8.667z"/>
            <path id="fold" fill="#FFF" d="M15.333 7.714V3.43l5.238 5.238h-4.285a.955.955 0 0 1-.953-.953z"/>
        </g>
        <path id="symbol" fill="url(#csv-a)" d="M1.282 0h8.865c.445 0 .607.046.77.134.163.087.29.215.378.378.087.163.134.324.134.77v8.865c0 .445-.047.607-.134.77a.909.909 0 0 1-.378.378c-.163.087-.325.134-.77.134H1.282c-.446 0-.607-.047-.77-.134a.909.909 0 0 1-.378-.378c-.088-.163-.134-.325-.134-.77V1.282C0 .836.046.675.134.512A.909.909 0 0 1 .512.134C.675.046.836 0 1.282 0z" transform="translate(2 6.762)"/>
        <path fill="#FFF" fill-rule="nonzero" d="M5.161 11.496l-1.127-.249c.137-.578.362-.994.677-1.248.314-.253.766-.38 1.356-.38.525 0 .926.074 1.202.221.277.148.475.348.594.601.118.254.178.715.178 1.383l-.011 1.769c0 .496.02.865.059 1.108.04.243.113.5.221.774H7.08l-.161-.626c-.212.252-.44.44-.682.567-.243.125-.5.188-.774.188-.456 0-.83-.153-1.121-.46-.292-.308-.437-.717-.437-1.227 0-.324.06-.606.178-.847.118-.24.285-.433.501-.577.216-.144.56-.271 1.035-.383.576-.133.976-.257 1.203-.372 0-.316-.023-.524-.068-.623a.524.524 0 0 0-.248-.242c-.12-.063-.29-.095-.51-.095-.222 0-.397.05-.525.151-.127.101-.23.29-.31.567zm1.66 1.229a6.24 6.24 0 0 1-.738.226c-.384.101-.636.212-.755.335a.653.653 0 0 0-.178.474c0 .22.066.404.197.553a.63.63 0 0 0 .494.224c.176 0 .35-.06.523-.181a.964.964 0 0 0 .358-.429c.067-.165.1-.465.1-.9v-.302zm2.943-.249h1.76v1.26c0 .714-.102 1.244-.306 1.591-.25.43-.668.75-1.255.959l-.344-.727c.347-.117.597-.275.75-.473.153-.199.234-.482.245-.85h-.85v-1.76z"/>
    </g>
</svg>

DejayJD avatar May 09 '19 22:05 DejayJD

Why not do something like this?

<div class="foo">
    <svg-icon src="assets/images/csv.svg"></svg-icon>
</div>

<div class="bar">
    <svg-icon src="assets/images/csv.svg"></svg-icon>
</div>
.foo {
    svg-icon {
        ::ng-deep svg {
            path[id=symbol] {
                fill: red;
            }
        }
    }
}

svg-icon-example

czeckd avatar May 10 '19 05:05 czeckd

For the original purpose that works, but where this would potentially be nice to have would be for the title and desc elements. According to CSSTricks Accessible SVGs, the title and desc should have unique IDs and then be referenced by an aria-labelledby attribute on the SVG itself.

localpcguy avatar Oct 29 '19 19:10 localpcguy

I am having the same problem. Apparently, other similar libraries take the approach of setting unique IDs as suggested here.

MaximSagan avatar Nov 29 '19 06:11 MaximSagan

For the original styling issue, now with v9.1.0, this works:

svg.red {
    path[id=symbol] {
        fill: red;
    }
}

svg.blue {
    path[id=symbol] {
        fill: blue;
    }
}
<svg-icon src="assets/csv.svg"></svg-icon>
<svg-icon src="assets/csv.svg" class="red"></svg-icon>
<svg-icon src="assets/csv.svg" class="blue"></svg-icon>

Also, I'm still thinking about good way to implement unique ids.

czeckd avatar Mar 09 '20 17:03 czeckd

I'm running into a similar issue with non-unique Ids within svgs. The svg I'm using has a path element with a fill attribute set to the value of a linearGradient's id. The second svg on the page is referencing the linearGradient of the first svg on the page via the id, and that element is not found for some reason. From what I can tell from a web search, this would be fixed if all svg ids were unique.

lizlux avatar Jun 29 '20 07:06 lizlux