SVG File With Dynamic Fill Colors - Vue - css

I am making a twitter clone application with VueJS 3.
I saved Twitter's logo as a .svg file and can use it with the <img /> tag. I can also change its color when I give the <svg> tag the fill="#fff" attribute. However, I want to use this .svg file in multiple places and in different colors.
So I tried to dynamically change the color of the svg by giving the <img /> tag the classes fill-white, bg-white and text-white, but it didn't work.
My Currently .svg File - With White Color
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24" aria-hidden="true">
<g>
<path fill="#fff" d="M23.643 4.937c-... 1.7-1.477 2.323-2.41z"></path>
</g>
</svg>
Img Tag
<img
src="/twitter-bird.svg"
draggable="false"
class="w-52 lg:w-96 fill-white"
alt="Twitter Bird"
/>
I Tried This On .svg File
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24" aria-hidden="true">
<g>
<path fill="params(fill) #fff" d="M23.643 4.937c-... 1.7-1.477 2.323-2.41z"></path>
</g>
</svg>
I understand that I need to make this svg's color editable. But I couldn't find how to do this.

You can make component from svg file and bind fill to prop:
const app = Vue.createApp({
data() {
return {
colors: ['#8A2BE2', 'rgb(255,255,0)', '#008000'],
};
},
})
app.component('myImg', {
template: `
<svg height="40" viewBox="0 0 107.1 107.1" style="enable-background:new 0 0 107.1 107.1;" xml:space="preserve">
<path :fill="color" d="M2.287,47.815l23.096,19.578L18.2,96.831c-1.411,5.491,4.648,9.998,9.575,6.901L53.55,87.813l25.774,15.916 c4.79,2.955,10.844-1.408,9.576-6.902l-7.184-29.435l23.099-19.579c4.363-3.661,2.111-10.844-3.662-11.267l-30.282-2.255 L59.464,6.266c-2.112-5.211-9.577-5.211-11.832,0L36.225,34.292L5.944,36.547C0.174,37.113-2.081,44.154,2.287,47.815z"/>
</svg>
`,
props: ['color']
})
app.mount('#demo')
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>
<div id="demo">
<div v-for="col in colors">
<my-img :color="col"></my-img>
</div>
</div>

const app = Vue.createApp({
data() {
return {
colors: ['#8A2BE2', 'rgb(255,255,0)', '#008000'],
};
},
})
app.component('myImg', {
template: `
<svg height="40" viewBox="0 0 107.1 107.1" style="enable-background:new 0 0 107.1 107.1;" xml:space="preserve">
<path :fill="color" d="M2.287,47.815l23.096,19.578L18.2,96.831c-1.411,5.491,4.648,9.998,9.575,6.901L53.55,87.813l25.774,15.916 c4.79,2.955,10.844-1.408,9.576-6.902l-7.184-29.435l23.099-19.579c4.363-3.661,2.111-10.844-3.662-11.267l-30.282-2.255 L59.464,6.266c-2.112-5.211-9.577-5.211-11.832,0L36.225,34.292L5.944,36.547C0.174,37.113-2.081,44.154,2.287,47.815z"/>
</svg>
`,
props: ['color']
})
app.mount('#demo')
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>
<div id="demo">
<div v-for="col in colors">
<my-img :color="col"></my-img>
</div>
</div>

Related

SVG rect resizing on hover

I'm trying to change the height of rectangles in my svg on hover. I can't for the life of me figure this out and I'd love some help. This is a very simple version of the SVG
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns:bx="https://boxy-svg.com"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 900 350"
style="enable-background:new 0 0 900 350;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FF0000;}
.st1{fill:#FED52A;}
.st2{fill:#00B3E4;}
</style>
<rect id="red" class="st0" width="280" height="350"/>
<rect id="yellow" x="620" class="st1" width="280" height="350"/>
<rect id="blue" x="310" class="st2" width="280" height="350"/>
<rect id="smallred" y="297" class="st0" width="280" height="53"/>
</svg>
I want the size of "red" rectangle to smoothly transition to the size of "small red" on hover and then smoothly transition back when not hovering over it. Ideally I want this all to happen within the SVG. Can anyone help or point me in the right direction?
You can't affect width/height of a rect in an SVG with CSS but you can transform it vertically to the required height.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
::before,
::after {
box-sizing: inherit;
}
#red {
transition: transform 1s ease;
}
#red:hover {
transform: scaleY(calc(53/350));
}
svg {
height: 90vh;
}
<svg version="1.1" id="Layer_1" xmlns:bx="https://boxy-svg.com" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 900 350" style="enable-background:new 0 0 900 350;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FF0000;}
.st1{fill:#FED52A;}
.st2{fill:#00B3E4;}
</style>
<rect id="red" class="st0" width="280" height="350"/>
<rect id="yellow" x="620" class="st1" width="280" height="350"/>
<rect id="blue" x="310" class="st2" width="280" height="350"/>
<rect id="smallred" y="297" class="st0" width="280" height="53"/>
</svg>

SVG sprite in CSS content attribute

I have a given svg-sprite:
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="envelope" viewBox="0 0 512 512">
<path d="M502.3 190.8c3.9-3.1 ...."></path>
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" id="menu-2">
<path d="M0 3h50v2H0zm0 14h50v2H0zm0 14h50v2H0zm0 14h50v2H0z"></path>
</symbol>
</svg>
Now i would like to add the second symbol (menu-2) to the ":after" of mydiv
mydiv:after {
content: url("somehow add menu-2 from svg sprite");
}
How can i reference it?
mydiv:after {
content: url(http://server/sprite.svg#menu-2);
}
where -
http://server path to the server or to the folder where the svg file is stored
#menu-2 - The called part of the sprite

Fill Colour on <use> Element For a <symbol> Isn't Changing Colour

I'm trying to change the fill colour on an SVG symbol when it is inside a <use> element. Because there are going to be multiple instances of the symbol on the page, I can't do this is the <symbol> element, because the different instances of <use> will be different colours.
I've can't seem to get it work though. In the example below I would like to the bottom instance to be a blue twitter icon.
In the CSS I've done #bottom-twitter svg path {fill:blue;} which doesn't work. And I can't seem to get anything to work.
Any help would be amazing.
#box1 {
height: 5rem;
width: 5rem;
}
/* NOT WORKING */
#bottom-twitter svg path {
fill:blue;
}
<svg id="twitter" style="display: none;">
<defs>
<symbol id="twitter-symbol" viewBox="0 0 19.19 15.95">
<path id="twitter-path" d="M19.19,1.92a8.76,8.76,0,0,1-2.28.64A3.9,3.9,0,0,0,18.63.32a6.87,6.87,0,0,1-2.52,1A3.87,3.87,0,0,0,13.23,0,4,4,0,0,0,9.32,4,3.41,3.41,0,0,0,9.44,5,11,11,0,0,1,1.32.72a4.29,4.29,0,0,0-.52,2A4,4,0,0,0,2.56,6.12,3.61,3.61,0,0,1,.76,5.6v0a4,4,0,0,0,3.16,4,4.35,4.35,0,0,1-1,.16,4.9,4.9,0,0,1-.76-.08,4,4,0,0,0,3.68,2.8A7.79,7.79,0,0,1,.92,14.19a6.78,6.78,0,0,1-.92,0A10.83,10.83,0,0,0,6,16c7.24,0,11.19-6.16,11.19-11.47V4a6.83,6.83,0,0,0,2-2">
</path>
</symbol>
</defs>
</svg>
<div class="box" id="box1">
<svg id="top-twitter" viewBox="0 0 19.19 15.95">
<use xlink:href="#twitter-symbol"/>
</svg>
<svg id="bottom-twitter" viewBox="0 0 19.19 15.95">
<use xlink:href="#twitter-symbol"/>
</svg>
</div>
The problem is the fill="#000" in the svg path. Remove that or just change it to be the color you want.
#box1 {
height: 5rem;
width: 5rem;
}
/* NOT WORKING */
#bottom-twitter {
fill: blue;
}
<svg id="twitter" style="display: none;">
<defs>
<symbol id="twitter-symbol" viewBox="0 0 19.19 15.95">
<path id="twitter-path" d="M19.19,1.92a8.76,8.76,0,0,1-2.28.64A3.9,3.9,0,0,0,18.63.32a6.87,6.87,0,0,1-2.52,1A3.87,3.87,0,0,0,13.23,0,4,4,0,0,0,9.32,4,3.41,3.41,0,0,0,9.44,5,11,11,0,0,1,1.32.72a4.29,4.29,0,0,0-.52,2A4,4,0,0,0,2.56,6.12,3.61,3.61,0,0,1,.76,5.6v0a4,4,0,0,0,3.16,4,4.35,4.35,0,0,1-1,.16,4.9,4.9,0,0,1-.76-.08,4,4,0,0,0,3.68,2.8A7.79,7.79,0,0,1,.92,14.19a6.78,6.78,0,0,1-.92,0A10.83,10.83,0,0,0,6,16c7.24,0,11.19-6.16,11.19-11.47V4a6.83,6.83,0,0,0,2-2" >
</path>
</symbol>
</defs>
</svg>
<div class="box" id="box1">
<svg id="top-twitter" viewBox="0 0 19.19 15.95">
<use xlink:href="#twitter-symbol"/>
</svg>
<svg id="bottom-twitter" viewBox="0 0 19.19 15.95">
<use xlink:href="#twitter-symbol"/>
</svg>
</div>

Over-write SVG DOM in use link tag

I'm displaying my SVG using use tag. I have all fill property in a separate class. On some event i will be need to change SVG elements colour. But unable to change the color. Don't know what mistake i'm into.
.red{
fill:red;
}
.overwrite .red{
fill:blue;
}
<div class="overwrite">
<svg width="18" height="18" viewBox="0 0 18 18">
<use xlink:href="#owned"></use>
</svg>
</div>
<svg width="18" height="18" viewBox="0 0 18 18" style="display:none" ><g id="owned" class="red">
<path d="M10.3841197,9.97075733 L13.2351431,11.4015266 C14.9626648,11.9616921 15.8309505,12.9557364 15.9891455,14.4719879 C16.0178014,14.7466403 15.8183819,14.9925193 15.5437298,15.0211745 C15.5264933,15.0229729 15.5091749,15.0238739 15.4918448,15.0238739 L2.51884261,15.0238739 C2.24273586,15.0238522 2.01888584,14.7999955 2.01888584,14.5238739 C2.01888584,14.5045273 2.0200088,14.4851971 2.02224906,14.4659807 C2.19872996,12.9521713 3.06467543,11.9595935 4.69306731,11.4301408 L7.61375396,9.97075733 L7.1652223,9.07699038 L4.31419892,10.5077596 C2.39480463,11.1258644 1.25218198,12.4355796 1.02897609,14.3501842 C1.02225492,14.4078368 1.01888584,14.4658309 1.01888584,14.5238739 C1.01888584,15.3522606 1.69041424,16.023809 2.51880347,16.0238739 L9.09090532,16.0238739 L15.4918448,16.0238739 C15.543835,16.0238739 15.59579,16.0211709 15.6474995,16.0157759 C16.4714553,15.9298101 17.0697142,15.1921727 16.9837468,14.3682171 C16.7828597,12.4427753 15.6331205,11.126513 13.6120656,10.4785171 L10.8326513,9.07699038 L10.3841197,9.97075733 Z"/>
<path d="M11.9769889,4.48241206 C11.9769889,2.54800219 10.807176,1.5 8.97698892,1.5 C7.12089292,1.5 5.97698892,2.53355002 5.97698892,4.48241206 C5.97698892,6.87094598 7.51565932,9.5 8.97698892,9.5 C10.4383185,9.5 11.9769889,6.87094598 11.9769889,4.48241206 Z M12.9769889,4.48241206 C12.9769889,7.3505461 11.1337512,10.5 8.97698892,10.5 C6.82022662,10.5 4.97698892,7.3505461 4.97698892,4.48241206 C4.97698892,1.9573661 6.58996061,0.5 8.97698892,0.5 C11.3364486,0.5 12.9769889,1.96971351 12.9769889,4.48241206 Z"/>
</g>
</svg>
Refer sample code attached above
PS: Check the .overwrite class is not working.
Refer fiddle
use tag usually creates shadow root. You can't access class inside the shadow root. Instead try adding class .red to use tag.
.red{
fill:red;
}
.overwrite .red{
fill:blue;
}
<div class="overwrite">
<svg width="18" height="18" viewBox="0 0 18 18">
<use xlink:href="#owned" class="red"></use>
</svg>
</div>
<svg width="18" height="18" viewBox="0 0 18 18" style="display:none">
<g id="owned">
<path d="M10.3841197,9.97075733 L13.2351431,11.4015266 C14.9626648,11.9616921 15.8309505,12.9557364 15.9891455,14.4719879 C16.0178014,14.7466403 15.8183819,14.9925193 15.5437298,15.0211745 C15.5264933,15.0229729 15.5091749,15.0238739 15.4918448,15.0238739 L2.51884261,15.0238739 C2.24273586,15.0238522 2.01888584,14.7999955 2.01888584,14.5238739 C2.01888584,14.5045273 2.0200088,14.4851971 2.02224906,14.4659807 C2.19872996,12.9521713 3.06467543,11.9595935 4.69306731,11.4301408 L7.61375396,9.97075733 L7.1652223,9.07699038 L4.31419892,10.5077596 C2.39480463,11.1258644 1.25218198,12.4355796 1.02897609,14.3501842 C1.02225492,14.4078368 1.01888584,14.4658309 1.01888584,14.5238739 C1.01888584,15.3522606 1.69041424,16.023809 2.51880347,16.0238739 L9.09090532,16.0238739 L15.4918448,16.0238739 C15.543835,16.0238739 15.59579,16.0211709 15.6474995,16.0157759 C16.4714553,15.9298101 17.0697142,15.1921727 16.9837468,14.3682171 C16.7828597,12.4427753 15.6331205,11.126513 13.6120656,10.4785171 L10.8326513,9.07699038 L10.3841197,9.97075733 Z"/>
<path d="M11.9769889,4.48241206 C11.9769889,2.54800219 10.807176,1.5 8.97698892,1.5 C7.12089292,1.5 5.97698892,2.53355002 5.97698892,4.48241206 C5.97698892,6.87094598 7.51565932,9.5 8.97698892,9.5 C10.4383185,9.5 11.9769889,6.87094598 11.9769889,4.48241206 Z M12.9769889,4.48241206 C12.9769889,7.3505461 11.1337512,10.5 8.97698892,10.5 C6.82022662,10.5 4.97698892,7.3505461 4.97698892,4.48241206 C4.97698892,1.9573661 6.58996061,0.5 8.97698892,0.5 C11.3364486,0.5 12.9769889,1.96971351 12.9769889,4.48241206 Z"/>
</g>
</svg>
You are doing all right just end your <div class="overwrite"> bit early . Just end </div> tag at the end :)
.red{
fill:red;
}
.overwrite .red{
fill:blue;
}
<div class="overwrite">
<svg width="18" height="18" viewBox="0 0 18 18">
<use xlink:href="#owned"></use>
</svg>
<svg width="18" height="18" viewBox="0 0 18 18" style="display:none" ><g id="owned" class="red">
<path d="M10.3841197,9.97075733 L13.2351431,11.4015266 C14.9626648,11.9616921 15.8309505,12.9557364 15.9891455,14.4719879 C16.0178014,14.7466403 15.8183819,14.9925193 15.5437298,15.0211745 C15.5264933,15.0229729 15.5091749,15.0238739 15.4918448,15.0238739 L2.51884261,15.0238739 C2.24273586,15.0238522 2.01888584,14.7999955 2.01888584,14.5238739 C2.01888584,14.5045273 2.0200088,14.4851971 2.02224906,14.4659807 C2.19872996,12.9521713 3.06467543,11.9595935 4.69306731,11.4301408 L7.61375396,9.97075733 L7.1652223,9.07699038 L4.31419892,10.5077596 C2.39480463,11.1258644 1.25218198,12.4355796 1.02897609,14.3501842 C1.02225492,14.4078368 1.01888584,14.4658309 1.01888584,14.5238739 C1.01888584,15.3522606 1.69041424,16.023809 2.51880347,16.0238739 L9.09090532,16.0238739 L15.4918448,16.0238739 C15.543835,16.0238739 15.59579,16.0211709 15.6474995,16.0157759 C16.4714553,15.9298101 17.0697142,15.1921727 16.9837468,14.3682171 C16.7828597,12.4427753 15.6331205,11.126513 13.6120656,10.4785171 L10.8326513,9.07699038 L10.3841197,9.97075733 Z"/>
<path d="M11.9769889,4.48241206 C11.9769889,2.54800219 10.807176,1.5 8.97698892,1.5 C7.12089292,1.5 5.97698892,2.53355002 5.97698892,4.48241206 C5.97698892,6.87094598 7.51565932,9.5 8.97698892,9.5 C10.4383185,9.5 11.9769889,6.87094598 11.9769889,4.48241206 Z M12.9769889,4.48241206 C12.9769889,7.3505461 11.1337512,10.5 8.97698892,10.5 C6.82022662,10.5 4.97698892,7.3505461 4.97698892,4.48241206 C4.97698892,1.9573661 6.58996061,0.5 8.97698892,0.5 C11.3364486,0.5 12.9769889,1.96971351 12.9769889,4.48241206 Z"/>
</g>
</svg>
</div>

Apply different CSS to <use> tag from one symbol svg?

I defined an svg icon like this
<svg style="display: none">
<symbol id="icon-check-mark-3" viewBox="0 0 200 200">
<title>check-mark-3</title>
<path fill="#fcc083" class="path1 fill-color2" d="M99.875 11.584c-48.968 0-88.666 39.697-88.666 88.666s39.698 88.666 88.666 88.666 88.666-39.698 88.666-88.666c0-48.969-39.698-88.666-88.666-88.666zM150.97 69.963l-48.493 67.173c-4.055 5.62-12.535 5.618-16.59 0l-25.396-35.181c-3.307-4.582-2.273-10.978 2.307-14.284 4.584-3.306 10.977-2.272 14.283 2.307l17.101 23.69 40.197-55.68c3.305-4.582 9.699-5.615 14.282-2.306 4.582 3.306 5.616 9.701 2.308 14.281z"></path>
</symbol>
</svg>
<p id="first">my first image
<use xlink:href="#icon-check-mark-3"></use>
</svg>
</p>
<p id="second">my second image
<use xlink:href="#icon-check-mark-3"></use>
</svg>
</p>
I need to color the #first icon in red.
I have spent nearly 2 hours to find the way to do this but I can't.
First, you are missing the <svg> opening tag in your paragraphs. Second, you need to remove the fill property on the symbol, then you will be able to specify the color of each svg with CSS like this :
#first svg {
fill: red;
}
#second svg {
fill: #fcc083;
}
<svg style="display: none">
<symbol id="icon-check-mark-3" viewBox="0 0 200 200">
<title>check-mark-3</title>
<path class="path1 fill-color2" d="M99.875 11.584c-48.968 0-88.666 39.697-88.666 88.666s39.698 88.666 88.666 88.666 88.666-39.698 88.666-88.666c0-48.969-39.698-88.666-88.666-88.666zM150.97 69.963l-48.493 67.173c-4.055 5.62-12.535 5.618-16.59 0l-25.396-35.181c-3.307-4.582-2.273-10.978 2.307-14.284 4.584-3.306 10.977-2.272 14.283 2.307l17.101 23.69 40.197-55.68c3.305-4.582 9.699-5.615 14.282-2.306 4.582 3.306 5.616 9.701 2.308 14.281z"></path>
</symbol>
</svg>
<p id="first">my first image
<svg>
<use xlink:href="#icon-check-mark-3"></use>
</svg>
</p>
<p id="second">my second image
<svg>
<use xlink:href="#icon-check-mark-3"></use>
</svg>
</p>
Use fill="currentColor" to set color to your svgs by color css attribute.
.red {
color: red;
}
.green {
color: green;
}
svg {
width: 12px;
height: 12px;
}
<svg style="display: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="12" height="12" viewBox="0 0 12 12">
<path fill="currentColor" id="delete" d="M7.249,5.977 C7.249,5.977 11.863,10.606 11.863,10.606 C11.978,10.724 11.975,10.917 11.856,11.039 C11.856,11.039 11.036,11.877 11.036,11.877 C10.917,11.998 10.726,12.001 10.611,11.883 C10.611,11.883 5.992,7.248 5.992,7.248 C5.992,7.248 1.308,11.850 1.308,11.850 C1.194,11.966 1.005,11.963 0.887,11.843 C0.887,11.843 0.076,11.014 0.076,11.014 C-0.043,10.893 -0.046,10.701 0.069,10.584 C0.069,10.584 4.659,5.977 4.659,5.977 C4.659,5.977 0.069,1.368 0.069,1.368 C-0.046,1.251 -0.043,1.060 0.076,0.939 C0.076,0.939 0.887,0.110 0.887,0.110 C1.005,-0.011 1.194,-0.013 1.308,0.104 C1.308,0.104 5.992,4.704 5.992,4.704 C5.992,4.704 10.611,0.070 10.611,0.070 C10.726,-0.048 10.917,-0.045 11.036,0.076 C11.036,0.076 11.856,0.914 11.856,0.914 C11.975,1.035 11.978,1.230 11.863,1.347 C11.863,1.347 7.249,5.977 7.249,5.977 Z" />
</svg>
<p class="red">
<svg>
<use xlink:href="#delete"></use>
</svg>
red
</p>
<p class="green">
<svg>
<use xlink:href="#delete"></use>
</svg>
green
</p>

Resources