How to insert an SVG into a button? - html

I am new to HTML and stuff and I would like to insert a SVG into a button. I tried using <object> but the SVG is invisible. Any suggestions what I could do to make it visible and fit inside the box?

There are a few different approaches. Possibly the easiest way to include an SVG is using an <img> tag, like you would for any other image type:
<button>
<img src="https://api.iconify.design/ic-baseline-face.svg?height=24" aria-hidden="true">
Smile
</button>
In this case, the size of the SVG we're importing is about right, but if it wasn't it might be more difficult to size it how you like, because you have two elements rather than one to think about. In that case, a good alternative is to set it as a background in CSS instead:
.my-button {
width: 3em;
height: 3em;
background: url("https://api.iconify.design/ic-baseline-face.svg?height=24") center no-repeat;
}
<button class="my-button" aria-label="Smile"></button>
This approach is often used for icons, but note that in this method we have to specify a size (in this case using width and height in the CSS).
As a third option, you can include SVG source directly in HTML instead, which allows you to style it with CSS and manipulate it with JavaScript, but that's generally not very useful for button icons. For completeness, though you'd do it like this:
<button>
<!-- From https://material.io/tools/icons/?style=baseline -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M9 11.75c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zm6 0c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37C11.07 8.33 14.05 10 17.42 10c.78 0 1.53-.09 2.25-.26.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8z"/>
<path fill="none" d="M0 0h24v24H0z"/>
</svg>
</button>
CSS-Tricks has a good article on all three methods.

Related

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

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" class="w-28 sm:w-48 md:w-60" />
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" class="w-28 sm:w-48 md:w-60" fill="#222" />
I assumed that would do the trick but it did not. after plenty of research, I still can't find a solution.
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.)
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 class="w-28 sm:w-48 md:w-60" 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

Coveo Atomic Search Interface Styling - Atomic-Icon - Shadow Dom

I am trying to style Coveo's new Atomic React Wrapper using Shadow Dom. It doesn't appear they exposed the atomic-icon's svg elements as a part for both submit-button and clear-button. I was able to modify their colors by changing some of the variables.
atomic-search-box::part(clear-button){ width: 50px; height: 50px; }
This will affect the background of the svg but not the icon itself. Here is the rendered html of clear-button.
<button class="btn-text-transparent w-8 h-8 mr-1.5 text-neutral-dark ripple-parent ripple-relative" part="clear-button" aria-label="Clear"><atomic-icon class="w-3 h-3 hydrated ripple-relative" innerhtml="<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"><path d="m18 2-1.8-2-7.1 7.1-7.1-7.1-2 2 7.1 7.1-7.1 7.1 2 1.8 7.1-6.9 7.1 6.9 1.8-1.8-6.9-7.1z"></path></svg>"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"><path d="m18 2-1.8-2-7.1 7.1-7.1-7.1-2 2 7.1 7.1-7.1 7.1 2 1.8 7.1-6.9 7.1 6.9 1.8-1.8-6.9-7.1z"></path></svg></atomic-icon></button>
it looks like height and width are pulled from .w-3 .h-3 classes on the atomic-icon.
.h-3 {
height: 0.75rem;
}
Can I override those classes somehow or how would you increase the size of these elements?
At the time when you asked your question, there was indeed no easy way to edit those components.
However, within the last weeks, the clear-icon and submit-icon shadow parts have been released: https://docs.coveo.com/en/atomic/latest/reference/components/atomic-search-box/
I hope this helps!

How to modify svg icon colors with Tailwind

I'm using TailwindCSS and want to change the color of an svg. Without Tailwind this question has been asked before here, for 2020 this should be a good answer but Tailwind does not support those filters. There is a guide in the docs on how to work with svg icons but this tutorial works without files, just the plain text paths.
I downloaded the svg files and assign the path to the svg to the image's src tag. The following example shows my problem, I want the icon's background to be red and the icon's color to be blue. Unfortunately it's not possible for me to change the icon color.
<link href="https://unpkg.com/tailwindcss#1.8.10/dist/tailwind.min.css" rel="stylesheet" />
<!-- taken from here https://www.iconfinder.com/icons/765208/media_twitter_social_icon -->
<img class="fill-current bg-red-500 text-blue-500" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSI2MHB4IiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA2MCA2MCIgd2lkdGg9IjYwcHgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48dGl0bGUvPjxkZXNjLz48ZGVmcy8+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBpZD0iYmxhY2siIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIj48ZyBpZD0ic2xpY2UiLz48ZyBmaWxsPSIjMDAwMDAwIiBpZD0idHdpdHRlciIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTMuMDAwMDAwLCAxNi4wMDAwMDApIj48cGF0aCBkPSJNMjguMDUyMTM4NSwyLjQzNjY5NDI3IEMyNi44NDMxODQ2LDEuMDYyMjAxNSAyNS4xMjA1Mzg1LDAuMTg2NDY0MTA1IDIzLjIxNDA2MTUsMC4xNTQ3MzEwMjggQzE5LjU1MzYsMC4wOTM4MDMwOTA1IDE2LjU4NTY1MzgsMy4xODY5MjMzOSAxNi41ODU2NTM4LDcuMDYzMTE2MDQgQzE2LjU4NTY1MzgsNy42MTMyNDExOCAxNi42NDQyOTIzLDguMTQ5NjkzMzcgMTYuNzU3MzY5Miw4LjY2NDY3MzE2IEMxMS4yNDg1ODQ2LDguMzA3MzUyNTcgNi4zNjQ0NjkyMyw1LjQzODc3MDU5IDMuMDk1NDE1MzgsMS4xMTQ3MjE4IEMyLjUyNDg2MTU0LDIuMTUwODYxNyAyLjE5NzkwNzY5LDMuMzYxODgyNzEgMi4xOTc5MDc2OSw0LjY1OTE1MDM3IEMyLjE5NzkwNzY5LDcuMTE0OTg4NDQgMy4zNjgwOTIzMSw5LjI5NDUyNzI0IDUuMTQ2NjMwNzcsMTAuNTgxNDE3NCBDNC4wNjAxMjMwOCwxMC41MzM0NDk5IDMuMDM4MDY5MjMsMTAuMjA0NTM3OCAyLjE0NDQzODQ2LDkuNjY0OTUyMDMgQzIuMTQzNzkyMzEsOS42OTQ0NDQ5NyAyLjE0Mzc5MjMxLDkuNzIzOTQ0OTQgMi4xNDM3OTIzMSw5Ljc1Mzk2MjQ1IEMyLjE0Mzc5MjMxLDEzLjE4MzU0OTcgNC40Mjg1OTIzMSwxNi4wNjA3MDc2IDcuNDYwODMwNzcsMTYuNzMwOTM4MyBDNi45MDQ2NTM4NSwxNi44ODg1MzggNi4zMTkwNzY5MiwxNi45NzEwMTYzIDUuNzE0NiwxNi45NjcwMDggQzUuMjg3NDkyMzEsMTYuOTY0MTc1OCA0Ljg3MjE3NjkyLDE2LjkxNjgxMTggNC40Njc1MjMwOCwxNi44MzE3NjggQzUuMzEwOTE1MzgsMTkuNjQ0Mzc3NyA3Ljc1ODcwNzY5LDIxLjY5Njc2NjMgMTAuNjU5MjkyMywyMS43NjQ2MjggQzguMzkwODA3NjksMjMuNjQ3Njk2MyA1LjUzMjg2OTIzLDI0Ljc2OTE5MzMgMi40MjcyOTIzMSwyNC43NjI3ODcgQzEuODkyMjc2OTIsMjQuNzYxNjgzMyAxLjM2NDY5MjMxLDI0LjcyNzExMiAwLjg0NjE1Mzg0NiwyNC42NjA1OTk2IEMzLjc3OTUzMDc3LDI2LjY3MzMxMzkgNy4yNjM1OTIzMSwyNy44NDUxNzExIDExLjAwNjc2MTUsMjcuODQ2MTUzMSBDMjMuMTk4NTUzOCwyNy44NDkzNTE4IDI5Ljg2NTczMDgsMTcuMjM5NTEwOSAyOS44NjU3MzA4LDguMDM2NzY4NjggQzI5Ljg2NTczMDgsNy43MzQ4MzYzMiAyOS44NTkxMDc3LDcuNDM0NTE5MTIgMjkuODQ2NTA3Nyw3LjEzNTY1MTk1IEMzMS4xNDE1NjE1LDYuMTcwNjY2NDUgMzIuMjY1MjIzMSw0Ljk2MDc4OTE1IDMzLjE1Mzg0NjIsMy41NzkyMTkwMSBDMzEuOTY1MjQ2Miw0LjExNTAxNjE1IDMwLjY4NzYzODUsNC40NzA4Njg2MyAyOS4zNDcwMzA4LDQuNjIwMTM3ODkgQzMwLjcxNTQyMzEsMy43Nzc5NjUxOCAzMS43NjY1NTM4LDIuNDMwMDk2MDcgMzIuMjYxMzQ2MiwwLjgxMzc1ODQwNCBDMzAuOTgwNTA3NywxLjU5MDQ5MjI5IDI5LjU2MjAzODUsMi4xNDc1MTI4NiAyOC4wNTIxMzg1LDIuNDM2Njk0MjcgWiIvPjwvZz48L2c+PC9zdmc+">
What is the correct workflow when downloading svg icons and use them directly by linking the assets path? All I want to achieve is something like this
<a href="https://twitter.com" target="_blank">
<img src="pathToSvgInAssetsFolder" />
</a>
and set the icon color to a custom Tailwind color e.g. red-500. So whenever I want to change the icon color I can simply modify the color class.
Does someone know how to do it?
The workflow for adding SVG to your Tailwind project should be done using inline SVG.
Adam Watham the creator of Tailwind CSS made a video about working with inline SVG in Tailwind. In the video he shows a workflow you would use to prep an unoptimized SVG for a Tailwind project. Here's the steps with one extra step he didn't mention:
Drop the SVG file or paste the SVG markup into the optimizer at SVGOMG.
Copy the markup provided by SVGOMG and paste into your project.
Remove any fill or stroke attributes so Tailwind can modify those with classes (not shown in the video).
Remove any XMLNS attributes or XML tags, these are not needed for inline SVG.
Add Tailwind classes.
If you're using a component based framework it's recommended that you also extract the icons into components that can be reused throughout your application.
The benefits of this approach:
Full control over the size and color of your SVG icons
Faster load speed since the icons are part of the HTML
Here's an example based on the Fiddle you shared in the comments. I ran the SVGs through SVGOMG and removed the fill attributes so Tailwind can control that.
<link href="https://unpkg.com/tailwindcss#1.8.10/dist/tailwind.min.css" rel="stylesheet" />
<svg class="text-teal-500 fill-current h-16 w-16" viewBox="0 0 60 60">
<path d="M41.05 18.44a6.6 6.6 0 00-4.84-2.29c-3.66-.06-6.62 3.04-6.62 6.91 0 .55.05 1.09.17 1.6a18.68 18.68 0 01-13.66-7.55 7.33 7.33 0 00-.9 3.55 7.3 7.3 0 002.95 5.92 6.34 6.34 0 01-3-.92v.1c0 3.42 2.28 6.3 5.31 6.97a6.24 6.24 0 01-3 .1 6.74 6.74 0 006.2 4.93 12.8 12.8 0 01-9.81 2.9A17.89 17.89 0 0024 43.85c12.19 0 18.86-10.61 18.86-19.81l-.02-.9c1.3-.97 2.42-2.18 3.3-3.56-1.18.54-2.46.9-3.8 1.04a6.8 6.8 0 002.91-3.8c-1.28.77-2.7 1.33-4.2 1.62z"/>
</svg>
<svg class="bg-red-500 text-red-800 fill-current h-16 w-16 rounded-lg" viewBox="0 0 60 60">
<path d="M25.46 47.31V30h-3.52v-5.74h3.52v-3.47c0-4.68 1.4-8.06 6.53-8.06h6.1v5.73h-4.3c-2.15 0-2.64 1.43-2.64 2.92v2.88h6.62l-.9 5.74h-5.72V47.3h-5.69z"/>
</svg>
In simple terms use text-<color> and fill-current
<svg class="h-16 w-16 rounded-full bg-cyan-400 fill-current text-white" viewBox="0 0 60 60">
<path d="M25.46 47.31V30h-3.52v-5.74h3.52v-3.47c0-4.68 1.4-8.06 6.53-8.06h6.1v5.73h-4.3c-2.15 0-2.64 1.43-2.64 2.92v2.88h6.62l-.9 5.74h-5.72V47.3h-5.69z" />
</svg>
Output:

How to use SVG for icons properly / best practices

I'm looking for an advice about work with SVG images, respectively icons.
What I've tried
If I'm using PNG icons, the CSS is like:
elem:after {background: url('icon.png'); ...}
I've tried the same way
elem:after {background: url('icon.svg'); ...}
but it isn't what I'm looking for. This solution lose advantages of SVG icons (they're small and blured, fuzzy).
What I have
I've generated this code online using Icomoon app.
<svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-love" viewBox="0 0 33 32">
<title>love</title>
<path d="M32.916 15.597c0.604-0.66 ..."></path>
</symbol>
<symbol id="icon-shop" viewBox="0 0 34 32">
<title>shop</title>
<path d="M17.148 27.977c-..."></path>
</symbol>
</defs>
</svg>
<svg class="icon icon-shop">
<use xlink:href="#icon-shop"></use>
</svg>
My question
Is it semantically correct to put icons into HTML markup, instead of putting them into CSS?
Across whole website there is about 60 icons, any unique, any are repeated more times. Generated markup above has about 50kB.
Can I put all icons into general layout template and load them all in whole website, or include just icons I use in the page?
Here I've found How to change color of SVG image using CSS (jQuery SVG image replacement)? (3 years ago), but don't know if it's the right way.
How to cache SVG properly? Is it posible when I use it like I'm writing above?
I read many articles, but not definitely sure how to do that best way.
Thanks for advice.

Can't change size of `symbol` element from external svg with CSS, but other `symbol` in same file works

I'm hoping someone can point out where my bug is with this little problem I have.
I can't resize one <symbol> from an external svg with CSS, but I can another <symbol> from the same external svg.
In the CSS I'm changing the width and height. Which #pluss handles fine, whereas #heart completely ignores it. It just wants to stay at 24px * 24px regardless of CSS sizing.
I can't tell what I'm doing differently. Headscratchingly confusing!
The external icons-defs.svg file:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="pluss" viewBox="0 0 24 24" aria-labeledby="title">
<title>Add</title>
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</symbol>
<symbol id="heart" viewbox="0 0 24 24" aria-labeledby="title">
<title>Favourite</title>
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
</symbol>
</svg>
And in HTML:
<button>
<svg class="icon-heart" role="presentation">
<use xlink:href="icons-defs.svg#heart"></use>
</svg>
Like
</button>
<button>
<svg class="icon-pluss" role="presentation">
<use xlink:href="icons-defs.svg#pluss"></use>
</svg>
Add Goal
</button>
When having the same svg with symbols inline at top of the HTML document it works fine.
Any pointers would be much appreciated :)
#robert-longson wrote the solution in a comment, so I'm copy-pasting it here.
One symbol has a viewBox, one does not. SVG is case sensitive so viewbox is not a functional attribute. HTML is not case sensitive so it works inline when parsed by a HTML parser.
So changing viewbox to viewBox (capital B) fixed my bug.