Home > database >  Is there any way to import an SVG and then modify it?
Is there any way to import an SVG and then modify it?

Time:12-20

Here is an endpoint for a logo that I will use in the example: https://rdanhgsjebvnzzvsohyx.supabase.co/storage/v1/object/public/assets/logos/logoaidvisor-purple.svg

So importing and rendering the SVG as an image and styling it using Tailwind CSS works perfectly fine:

<img src="https://rdanhgsjebvnzzvsohyx.supabase.co/storage/v1/object/public/assets/logos/logoaidvisor-purple.svg" alt="logo"  />

However, I can't find a way to modify the SVG as I would be able to do with "normal" SVGs.

note: I am working in a svelte project but I wish to find a universal solution that works no matter the framework, etc.

I tried giving the image attributes that id usually would give to SVGs such as fill:

<img src="https://rdanhgsjebvnzzvsohyx.supabase.co/storage/v1/object/public/assets/logos/logoaidvisor-purple.svg" alt="logo"  fill="#222" />

I assumed that would do the trick but it did not. after plenty of research, I still can't find a solution.

CodePudding user response:

You simply cannot use img if you want to affect the SVG. Inline the SVG directly, that way styles can apply, as it generates the necessary elements that are targeted by the styles.

How exactly you would do this depends on your build system; many have ways of importing files as just their string contents, so you could e.g. use that in conjunction with {@html ...}. If the SVG comes from a DB you can create an API and fetch the contents from there.

(Note that SVGs can potentially execute scripts, so as with anything else, only use @html with secure/sanitized content.)

CodePudding user response:

You can also use an external <use> element – similar in convenience to an <img> element.

  • Wrap your logo in a <symbol> element and apply an ID.

  • Remove fill attributes from the logo's <path> elements and add them to the <use> element

  • Copy the original viewBox attribute to your parent svg

Example

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/1.5.1/tailwind.min.css">


<svg  viewBox="0 0 79 38">
  <use href="#logo" fill="#ccc" />
</svg>


<svg width="0" height="0" viewBox="0 0 79 38" fill="none" xmlns="http://www.w3.org/2000/svg">
  <symbol id="logo" viewBox="0 0 79 38">
<path d="M0 23C0 20.1333 0.533333 17.6167 1.6 15.45C2.7 13.2833 4.18333 11.6167 6.05 10.45C7.91667 9.28333 10 8.7 12.3 8.7C14.2667 8.7 15.9833 9.1 17.45 9.9C18.95 10.7 20.1 11.75 20.9 13.05V9.1H29.45V37H20.9V33.05C20.0667 34.35 18.9 35.4 17.4 36.2C15.9333 37 14.2167 37.4 12.25 37.4C9.98333 37.4 7.91667 36.8167 6.05 35.65C4.18333 34.45 2.7 32.7667 1.6 30.6C0.533333 28.4 0 25.8667 0 23ZM20.9 23.05C20.9 20.9167 20.3 19.2333 19.1 18C17.9333 16.7667 16.5 16.15 14.8 16.15C13.1 16.15 11.65 16.7667 10.45 18C9.28333 19.2 8.7 20.8667 8.7 23C8.7 25.1333 9.28333 26.8333 10.45 28.1C11.65 29.3333 13.1 29.95 14.8 29.95C16.5 29.95 17.9333 29.3333 19.1 28.1C20.3 26.8667 20.9 25.1833 20.9 23.05Z" fill="red" />
<path d="M44.1855 9.1V37H35.6355V9.1H44.1855Z" />
<path d="M48.6816 23C48.6816 20.1333 49.215 17.6167 50.2816 15.45C51.3816 13.2833 52.865 11.6167 54.7316 10.45C56.5983 9.28333 58.6816 8.7 60.9816 8.7C62.815 8.7 64.4816 9.08333 65.9816 9.85C67.515 10.6167 68.715 11.65 69.5816 12.95V0H78.1316V37H69.5816V33C68.7816 34.3333 67.6316 35.4 66.1316 36.2C64.665 37 62.9483 37.4 60.9816 37.4C58.6816 37.4 56.5983 36.8167 54.7316 35.65C52.865 34.45 51.3816 32.7667 50.2816 30.6C49.215 28.4 48.6816 25.8667 48.6816 23ZM69.5816 23.05C69.5816 20.9167 68.9816 19.2333 67.7816 18C66.615 16.7667 65.1816 16.15 63.4816 16.15C61.7816 16.15 60.3316 16.7667 59.1316 18C57.965 19.2 57.3816 20.8667 57.3816 23C57.3816 25.1333 57.965 26.8333 59.1316 28.1C60.3316 29.3333 61.7816 29.95 63.4816 29.95C65.1816 29.95 66.615 29.3333 67.7816 28.1C68.9816 26.8667 69.5816 25.1833 69.5816 23.05Z" />
<path d="M35.6 2.00104C35.6 0.896468 36.4954 0.0010376 37.6 0.0010376H42.6C43.7045 0.0010376 44.6 0.896468 44.6 2.00104V7.00104H37.6C36.4954 7.00104 35.6 6.10561 35.6 5.00104V2.00104Z" />
  </symbol>
</svg>

Limitations: strict CORS policy

External <use> references must be hosted on same domain – otherwise browsers will block them due to cross origin security settings.

Other features like gradients, masks, clip-paths etc. might also not work.

For simple use cases like logos or icons it's still a suitable alternative to <img>.

However you might use an injecting/inlining script like svgxuse

  • Related