shrpne / vue-inline-svg

Dynamically loads an SVG source and inline <svg> element so you can manipulate the style of it
MIT License
175 stars 21 forks source link

How to solve multiple svg style conflicts #57

Closed mdxiaohu closed 1 year ago

mdxiaohu commented 1 year ago

icon one : <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="119.141" height="137.378" viewBox="0 0 119.141 137.378" preserveAspectRatio="none meet"><defs><style>.a{fill:none;}.b{fill:url(#a);}.c{fill:url(#b);}.d{fill:url(#c);}.e{opacity:0.43;}.f{fill:url(#d);}.g{clip-path:url(#g);}.h{fill:url(#h);}.i{fill:url(#i);}.j{fill:url(#j);}</style><linearGradient id="a" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#0381ff" stop-opacity="0.102"/><stop offset="1" stop-color="#2b89ff" stop-opacity="0.2"/></linearGradient><radialGradient id="b" cx="0" cy="0.027" r="0.501" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#007dff" stop-opacity="0.302"/><stop offset="1" stop-color="#1f85ff" stop-opacity="0"/></radialGradient><radialGradient id="c" cx="0.5" cy="1" r="0.155" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#0083ff" stop-opacity="0.302"/><stop offset="1" stop-color="#1f85ff" stop-opacity="0"/></radialGradient><linearGradient id="d" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#0381ff" stop-opacity="0.58"/><stop offset="1" stop-color="#2b89ff" stop-opacity="0.612"/></linearGradient><clipPath id="g"><path class="a" d="M8,135.878a8,8,0,0,1-8-8V28A28,28,0,0,1,28,0h82.393a8,8,0,0,1,8,8V131.878a4,4,0,0,1-4,4Z"/></clipPath><linearGradient id="h" x1="0.813" y1="0.231" x2="0.247" y2="0.806" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#0076ff" stop-opacity="0"/><stop offset="0.535" stop-color="#0097ff" stop-opacity="0.231"/><stop offset="1" stop-color="#008cff" stop-opacity="0"/></linearGradient><linearGradient id="i" y1="0.167" x2="1" y2="0.167" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#ff900b"/><stop offset="1" stop-color="#ffc736"/></linearGradient><linearGradient id="j" x1="0.402" y1="0.1" x2="0.627" y2="0.5" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#0bc8ff"/><stop offset="1" stop-color="#2773ff"/></linearGradient></defs><g transform="translate(-1014.141 -480.641)"><g transform="translate(1014.889 482.141)"><path class="b" d="M28,0h82.393a8,8,0,0,1,8,8V131.878a4,4,0,0,1-4,4H8a8,8,0,0,1-8-8V28A28,28,0,0,1,28,0Z" transform="translate(0 0)"/><path class="c" d="M28,0h82.393a8,8,0,0,1,8,8V131.878a4,4,0,0,1-4,4H8a8,8,0,0,1-8-8V28A28,28,0,0,1,28,0Z" transform="translate(0 0)"/><path class="d" d="M28,0h82.393a8,8,0,0,1,8,8V131.878a4,4,0,0,1-4,4H8a8,8,0,0,1-8-8V28A28,28,0,0,1,28,0Z" transform="translate(0 0)"/><path class="a" d="M28,0h82.393a8,8,0,0,1,8,8V131.878a4,4,0,0,1-4,4H8a8,8,0,0,1-8-8V28A28,28,0,0,1,28,0Z" transform="translate(0 0)"/><path class="a" d="M28,0h82.393a8,8,0,0,1,8,8V131.878a4,4,0,0,1-4,4H8a8,8,0,0,1-8-8V28A28,28,0,0,1,28,0Z" transform="translate(0 0)"/></g><g transform="translate(1014.889 482.141)"><g class="e"><path class="f" d="M28,0h82.393a8,8,0,0,1,8,8V131.878a4,4,0,0,1-4,4H8a8,8,0,0,1-8-8V28A28,28,0,0,1,28,0Z"/><path class="c" d="M28,0h82.393a8,8,0,0,1,8,8V131.878a4,4,0,0,1-4,4H8a8,8,0,0,1-8-8V28A28,28,0,0,1,28,0Z"/><path class="d" d="M28,0h82.393a8,8,0,0,1,8,8V131.878a4,4,0,0,1-4,4H8a8,8,0,0,1-8-8V28A28,28,0,0,1,28,0Z"/><path class="a" d="M28,0h82.393a8,8,0,0,1,8,8V131.878a4,4,0,0,1-4,4H8a8,8,0,0,1-8-8V28A28,28,0,0,1,28,0Z"/><path class="a" d="M28,0h82.393a8,8,0,0,1,8,8V131.878a4,4,0,0,1-4,4H8a8,8,0,0,1-8-8V28A28,28,0,0,1,28,0Z"/></g><g class="g"><path class="h" d="M101.918,240.205,243.212,98.911l8.478,8.478L110.4,248.683ZM84.932,221.722,226.226,80.428l8.478,8.478L93.409,230.2ZM67.945,204.737,209.239,63.443l8.478,8.478L76.423,213.215ZM50.959,188.751,192.253,47.457l8.478,8.478L59.436,197.229ZM33.973,174.264,175.267,32.97l8.478,8.478L42.45,182.742ZM16.986,157.28,158.28,15.986l8.478,8.478L25.464,165.757ZM0,141.294,141.294,0l8.478,8.478L8.478,149.772Z" transform="translate(-62.897 -53.405)"/></g></g><path class="i" d="M0,0H8.992L0,8.992Z" transform="translate(1014.141 480.641)"/><path class="j" d="M0-22.573l1.859-1.637v-7.166L13.851-43.3h4.2l2.184-1.81H12.651L0-32.416Z" transform="translate(1015.139 526.746)"/></g></svg>

icon two :

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="34.739" height="38.422" viewBox="0 0 34.739 38.422"><defs><style>.a{stroke:rgba(0,0,0,0);stroke-miterlimit:10;fill:url(#a);}</style><linearGradient id="a" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#a9fffb"/><stop offset="1" stop-color="#0079ff"/></linearGradient></defs><path class="a" d="M10887.353,23593.75a3.024,3.024,0,0,1-1.507-.4l-13.921-8.035a3.027,3.027,0,0,1-1.5-2.568l-.159-15.68a2.991,2.991,0,0,1,1.526-2.643l13.656-7.7a3.006,3.006,0,0,1,2.978.012l13.921,8.041a3.008,3.008,0,0,1,1.5,2.564l.16,15.686a3,3,0,0,1-1.527,2.641l-13.656,7.7A3,3,0,0,1,10887.353,23593.75Zm-2.288-22.6a1.009,1.009,0,0,0-1.03.984v1.994l1.859.551a.8.8,0,0,1,.568.783v5.162c-.008.1-.092.934-.734,1.1-.557.141-2.9.617-3.664.771-.152.031-.244.051-.25.051s-.414.109-.414.285v.865h11.464v-.865c0-.174-.405-.289-.409-.289h.006l-.511-.1c-.941-.193-2.9-.594-3.409-.721-.643-.162-.727-1-.734-1.1v-5.166a.785.785,0,0,1,.568-.775l1.859-.551v-1.988a1.009,1.009,0,0,0-1.03-.984Zm2.066-4.658a6.853,6.853,0,0,1,4.755,1.873,6.208,6.208,0,0,1,1.966,4.527,6.369,6.369,0,0,1-3.73,5.738l.947,1.822a8.37,8.37,0,0,0,4.921-7.561,8.536,8.536,0,0,0-7.183-8.279v-.5a.678.678,0,0,0-.682-.658h-1.971a.677.677,0,0,0-.693.658v.5a8.531,8.531,0,0,0-7.17,8.279,8.366,8.366,0,0,0,4.914,7.561v-.012l.947-1.811a6.373,6.373,0,0,1-3.736-5.738A6.571,6.571,0,0,1,10887.131,23566.488Z" transform="translate(-10869.768 -23555.828)"/></svg>

have the same class .

.a {}

shrpne commented 1 year ago

As a workaround, you can use transformSource to edit class names.

This issue is related to #21 so closing as duplicate

mdxiaohu commented 1 year ago

@shrpne thank you for your reply . Sorry, I don't know much about this attribute . It would be great if you could provide an example . I use Google Translate, maybe the expression is not very good .

If there are many svg icons, a single custom processing may not be very good . Here is my current usage . ``

Is it possible to add properties to components to automatically isolate style interference .

mdxiaohu commented 1 year ago

@shrpne For example this plugin . https://github.com/webpack-contrib/svg-inline-loader He provides an attribute to avoid conflicts . ` classPrefix: boolean || string Adds a prefix to class names to avoid collision across svg files.

default: classPrefix: false

idPrefix: boolean || string Adds a prefix to ids to avoid collision across svg files.

default: idPrefix: false `

shrpne commented 1 year ago

Is it possible to add properties to components to automatically isolate style interference .

As i know, the only method to isolate styles in html is shadow dom, but i'm not aware how to use it

For example this plugin

Yes, you need to implement something what classPrefix does but with transformSource.

You need to pass function to transformSource props, this function accepts SVGElement as argument and returns transformed SVGElement

For inspiration for implementation of transform function you can use https://github.com/webpack-contrib/svg-inline-loader or https://github.com/gilbarbara/react-inlinesvg/blob/main/src/index.tsx#L296

vincerubinetti commented 1 year ago

I have an a loading spinner SVG like this:

<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="-50 -50 100 100"
  class="loading-spinner"
>
  <style>
    .loading-spinner {
      animation: spin 2s linear infinite forwards;
    }

    @keyframes spin {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
    }
  </style>
  <path
    fill="none"
    stroke="currentColor"
    stroke-width="10"
    d="M 0 40 A 40 40 0 1 1 40 0"
  />
</svg>

Then I use this package to import it, with an additional class on it

<InlineSvg
  :src="icon.src"
  class="icon"
/>

<style lang="scss" scoped>
.icon {
  height: 1em;
}
</style>

And the .loading-spinner class gets overwritten instead of merged.