How to rotate SVG back and forth on click? - css

So I have this arrow SVG which I am using for hiding/displaying a div. How can I rotate that arrow back and forth on every click?
Html:
<md-icon md-svg-icon="assets/svg/down-arrow.svg"></md-icon>
SVG:
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="arrow" x="0px" y="0px" viewBox="0 0 386.257 386.257" style="enable-background:new 0 0 386.257 386.257;" xml:space="preserve" width="24px" height="24px">
<polygon points="0,96.879 193.129,289.379 386.257,96.879 " fill="#e18327"/>
</svg>

It is very simple to do with CSS Transforms and JavaScript. Use JS to listen for the click event and when it happens toggle a class (which has the CSS transform: rotate) on or off.
In the below snippet, I've used an inline SVG (that is, SVG within the md-icon tag as the SVG file is not hosted anywhere to link to) but you can do that with external SVG files also. Just add the listener and set the class to the md-icon element or whatever is the element that contains the SVG.
document.querySelector('md-icon').addEventListener('click', function() {
this.classList.toggle('rotated');
});
.rotated {
transform: rotate(-90deg);
}
md-icon {
display: inline-block;
transition: all 1s;
}
<link href="http://rawgit.com/angular/bower-material/master/angular-material.min.css" rel="stylesheet"/>
<md-icon md-svg-icon='assets/svg/down-arrow.svg'>
<?xml version="1.0" encoding="iso-8859-1" ?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="arrow" x="0px" y="0px" viewBox="0 0 386.257 386.257" style="enable-background:new 0 0 386.257 386.257;" xml:space="preserve" width="24px" height="24px">
<polygon points="0,96.879 193.129,289.379 386.257,96.879 " fill="#e18327" />
</svg>
</md-icon>
We can of-course use two different SVG files and change the source (from down arrow to right arrow) on click but that wouldn't produce a smooth transition like the below snippet.
Another choice would have been to use SMIL animations but they are being deprecated and hence it is better to use CSS transforms.

Related

How do you render a different SVG onhover using react

I am trying to render a different color of the SVG I have on hover but I cant figure out the best way to do it.
When I looked up this question it tells me to use fill:{color} but I couldn't get that to work. I have tried creating two different SVG's one of the color I want normally(cancelBlack) and one of the color I want on hover(cancelBlue). I then tried doing this:
.cancelBlack:hover{
display:none;
}
.cancelBlue{
display: none;
}
.cancelBlue:hover{
display:flex;
}
//heres how im calling it in react
<button type="button" className='cancelBlack'>
<ReactSVG src={Cancel} />
</button>
<button type="button" className='cancelBlue'>
<ReactSVG src={CancelBlue} />
</button>
Here's the source code for the SVG:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<polyline fill="none" stroke="#4D4D4D" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
17.686,6.303 12,11.986 17.712,17.697 "/>
<polyline fill="none" stroke="#4D4D4D" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
6.316,6.303 12,11.986 6.289,17.697 "/>
</g>
</svg>
I wasn't sure how to undo the display none so I just went with display:flex. Thanks for any help.
You can use opacity or fill-opacity instead of display attr.
.cancelHover {
position: absolute;
z-index: 0;
}
.cancelNormal {
opacity: 1;
z-index: 1;
}
.cancelNormal:hover{
opacity: 0;
}
...
<button type="button" className='cancelHover'>
<ReactSVG src={CancelHover} />
</button>
<button type="button" className='cancelNormal'>
<ReactSVG src={CancelNormal} />
</button>
Another option:
You need to remove fill and stroke attrs in your svg files.
They are inline styles so you can't change it in your css style.
According to your svg files, it uses strokes so you need to change stroke colors in css.
.cancelNormal {
stroke: #4D4D4D;
z-index: 1;
}
.cancelNormal:hover{
stroke: #0000;
opacity: 0;
}
And also you can hide your svg image by using stroke-width: 0.
You probably need to do something like this:
Your CSS is targeting the SVG itself instead of the elements that make up the SVG.
.cancelBlue:hover { fill: #{color} }

Transparent svg with non-transparent background in css

I have an SVG inside a div like this
<div class="container">
<svg>...</svg>
</div>
with the following scss:
svg {
background-color: black;
fill: none;
}
what I expected was for the SVG to be transparent, with a black fill around it, so that you can see the background color of the container. I can not simply set the fill attribute to the background color, as I don't know what color it will be, beforehand.
Is there a simple solution to have an SVG with no fill attribute but a background color?
My SVG:
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="_x30_0_x5F_A" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"y="0px" viewBox="0 0 120 120" style="enable-background:new 0 0 120
120;" xml:space="preserve">
<path d="..."/>
</svg>

CSS Cursor pointer with SVG image

I'm trying to apply a custom cursor pointer with an SVG image but it's not working, instead if I use a png image everything is working fine.
Here's my code.
.container {
/* not working one */
cursor: url("/images/icon-cross.svg"), auto;
/* working one */
cursor: url("/images/icon-cross.png"), auto;
}
Is there any trick/workaround to make it working also with SVG or it's something which is not supported?
Thanks
UPDATE
Here's the svg code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path d="M443.6,387.1L312.4,255.4l131.5-130c5.4-5.4,5.4-14.2,0-19.6l-37.4-37.6c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4
L256,197.8L124.9,68.3c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4L68,105.9c-5.4,5.4-5.4,14.2,0,19.6l131.5,130L68.4,387.1
c-2.6,2.6-4.1,6.1-4.1,9.8c0,3.7,1.4,7.2,4.1,9.8l37.4,37.6c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1L256,313.1l130.7,131.1
c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1l37.4-37.6c2.6-2.6,4.1-6.1,4.1-9.8C447.7,393.2,446.2,389.7,443.6,387.1z"/>
</svg>
Your image is simply too large. Reduce the width and height to something less than 128px.
Icon size limits for cursors in CSS | MDN
...the limit of the cursor size is 128×128px. Larger cursor images are ignored.
Example:
cursor: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' ...") 16 16, pointer;
https://jsfiddle.net/bx4og7n5/
Edit: Added hotspot (center coordinates) for the cursor (see Dennis Bauszus' comment)
You can also use a Blob URL to insert inside the url function of CSS.
const blob = new Blob([**your SVG String**],{type: 'image/svg+xml'});
const URL = window.URL.createObjectURL(blob);
Now you can use this URL variable and can insert inside the url function of CSS to obtain desired cursor pointer.

How to display this SVG image where the img tag is

I am given a SVG file with the following content (a plus icon in black):
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1460px" height="610px" viewBox="0 0 1460 610" enable-background="new 0 0 1460 610" xml:space="preserve">
<g>
<path d="M746.602,304h-16v-16H729v16h-16v1.602h16v16h1.602v-16h16V304z M746.602,304"/>
</g>
</svg>
I would like to display it in a page with the following tag:
<img src="plus-icon-black.svg">
However the plus sign is displayed quite far from where the img tag is.
How can I display the svg image where the img tag is?
Your SVG image was saved with huge amounts of whitespace around the + shape.
Here is a clean version:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="449.1 991.8 33.6 33.6">
<path d="M482.7 1007.8h-16v-16h-1.6v16h-16v1.6h16v16h1.6v-16h16v-1.6z"/>
</svg>
You can control the size with CSS or using the <img> width or height attributes. Please reduce the artboard size to your shape's bounding-box when exporting to SVG in Illustrator.

SVG background on link - animating once on hover

I have an SVG set as a background image for a link. When you hover over the link the SVG is displayed and the animation is played once and then stops. This works great, except when you hover over the link a second time (or any other link with the SVG background), the animation doesn't start over.
Is there a way (other than setting the animation to loop) to get the SVG to start again on each hover? This is the code for the SVG:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.2" baseProfile="tiny" id="All_glyphs" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="10px" height="20px" viewBox="0 0 10 20" xml:space="preserve">
<rect x="0" y="20" width="10" height="20" fill="#7fffe5">
<animate attributeName="y" from="20" to="0" dur="500ms" fill="freeze" repeatCount="0"/>
</rect>
</svg>
And the CSS I use:
a:hover {
background-image: url(link.svg);
}
In the end I used background-position and CSS transitions to animate the background.

Resources