SVG animation is not working on IE11 - css

I have a really simple loading animation that works perfectly on Firefox and Chrome, but in IE11 it's not showing the SVG figure.
Here is the full example:
JSFiddle sample
SVG:
<svg class="circular-loader" viewBox="25 25 50 50">
<circle class="loader-path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"/>
</svg>
The animation, which is a rotation, is working on IE11, but the SVG, which is a circle, is not being displayed.
Any idea?
I just can't figure out what is not being supported by IE11.

Only Microsoft Edge will support SVG CSS Transitions and Animation.. especially stroke-dasharray.
Please see the Microsoft Developer Docs:
https://dev.windows.com/en-us/microsoft-edge/platform/status/csstransitionsanimationsforsvgelements
Allows CSS Transitions and Animations to apply to SVG elements.
Unprefixed version: Microsoft Edge build 10240+
As you can see in my fork of your example. You were not seeing the loader spin due to not having the stroke attribute on your circle element.
https://jsfiddle.net/z8w4vuau/50/
You can see how it can spin now. But you will have to check if the browser is IE and adjust your stroke-dasharray so it is larger dash. Since IE11 and below do not support animating SVG stroke-dasharray and stroke-dashoffset with CSS animation or transitions, unless it is Microsoft Edge build 10240+.
But if you need a cross browser solution to animate SVG, especially stroke-dasharray and stroke-dashoffset, then look into using a JS animation library like the GreenSock Animation Platform (GSAP). Using the DrawSVGPlugin
https://greensock.com/drawSVG

IE does not support CSS animation of SVG elements. It also doesn't support the standard built-in SMIL animations that SVG has.
If you convert your animation to native SVG animations, you could perhaps get it working using the FakeSmile library. Otherwise you will need to use some alternative fallback for IE - such as an animated gif or something.

IE11 supports CSS3 animations but not on child nodes of an SVG element. You can animate the SVG node itself so my solution is to break up the parts into separate SVGs and animate those with CSS3.
https://codepen.io/getsetbro/full/Bxeyaw/
This will even work if IE11 is in compatibility mode if you add the meta tag
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

For anyone having trouble with this, I have a workaround.
I had a full SVG with IDs and CSS animations, all working perfect for all the other major browsers.
I have my SVG inserted into the HTML, so I can access every item with CSS animations.
For this to work, you have to have your SVG with position:
absolute; top: 0px; left: 0px,
... inside a container .svgcontent (or whatever you want to call it)
Script:
var IE = (navigator.userAgent.indexOf("Edge") > -1 || navigator.userAgent.indexOf("Trident/7.0") > -1) ? true : false;
objs = [ '#file1', '#file2','#file3','#file4','#file5','#file6','#file7','#file8','#file9','#file10','#file11', '#bottom' ];
if ( IE ){
objs.forEach(function (item) {
item = $(item);
id = item.attr('id');
svgcontent = item.closest('.svgcontent')
svg = item.closest('svg');
svgattrs = ' width='+svg.attr('width')+' height='+svg.attr('height')+' '
html = '<svg id="'+id+'" '+svgattrs+'>'+item.html()+'</svg>';
item.remove();
$(svgcontent).prepend(html);
});
}
This takes all the elements in the objs array, and insert them as a full SVG behind the first one (you can change prepend to append to change this behavior).
And the SVG is going to have the same id as the object, so the CSS animate is going to apply to a full SVG, not an SVG object.
And that's it!

Related

CSS Animation w/ Translates Not Working in Internet Explorer [duplicate]

I have a really simple loading animation that works perfectly on Firefox and Chrome, but in IE11 it's not showing the SVG figure.
Here is the full example:
JSFiddle sample
SVG:
<svg class="circular-loader" viewBox="25 25 50 50">
<circle class="loader-path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"/>
</svg>
The animation, which is a rotation, is working on IE11, but the SVG, which is a circle, is not being displayed.
Any idea?
I just can't figure out what is not being supported by IE11.
Only Microsoft Edge will support SVG CSS Transitions and Animation.. especially stroke-dasharray.
Please see the Microsoft Developer Docs:
https://dev.windows.com/en-us/microsoft-edge/platform/status/csstransitionsanimationsforsvgelements
Allows CSS Transitions and Animations to apply to SVG elements.
Unprefixed version: Microsoft Edge build 10240+
As you can see in my fork of your example. You were not seeing the loader spin due to not having the stroke attribute on your circle element.
https://jsfiddle.net/z8w4vuau/50/
You can see how it can spin now. But you will have to check if the browser is IE and adjust your stroke-dasharray so it is larger dash. Since IE11 and below do not support animating SVG stroke-dasharray and stroke-dashoffset with CSS animation or transitions, unless it is Microsoft Edge build 10240+.
But if you need a cross browser solution to animate SVG, especially stroke-dasharray and stroke-dashoffset, then look into using a JS animation library like the GreenSock Animation Platform (GSAP). Using the DrawSVGPlugin
https://greensock.com/drawSVG
IE does not support CSS animation of SVG elements. It also doesn't support the standard built-in SMIL animations that SVG has.
If you convert your animation to native SVG animations, you could perhaps get it working using the FakeSmile library. Otherwise you will need to use some alternative fallback for IE - such as an animated gif or something.
IE11 supports CSS3 animations but not on child nodes of an SVG element. You can animate the SVG node itself so my solution is to break up the parts into separate SVGs and animate those with CSS3.
https://codepen.io/getsetbro/full/Bxeyaw/
This will even work if IE11 is in compatibility mode if you add the meta tag
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
For anyone having trouble with this, I have a workaround.
I had a full SVG with IDs and CSS animations, all working perfect for all the other major browsers.
I have my SVG inserted into the HTML, so I can access every item with CSS animations.
For this to work, you have to have your SVG with position:
absolute; top: 0px; left: 0px,
... inside a container .svgcontent (or whatever you want to call it)
Script:
var IE = (navigator.userAgent.indexOf("Edge") > -1 || navigator.userAgent.indexOf("Trident/7.0") > -1) ? true : false;
objs = [ '#file1', '#file2','#file3','#file4','#file5','#file6','#file7','#file8','#file9','#file10','#file11', '#bottom' ];
if ( IE ){
objs.forEach(function (item) {
item = $(item);
id = item.attr('id');
svgcontent = item.closest('.svgcontent')
svg = item.closest('svg');
svgattrs = ' width='+svg.attr('width')+' height='+svg.attr('height')+' '
html = '<svg id="'+id+'" '+svgattrs+'>'+item.html()+'</svg>';
item.remove();
$(svgcontent).prepend(html);
});
}
This takes all the elements in the objs array, and insert them as a full SVG behind the first one (you can change prepend to append to change this behavior).
And the SVG is going to have the same id as the object, so the CSS animate is going to apply to a full SVG, not an SVG object.
And that's it!

SVG mask not working in Firefox

I should apply SVG masks to few of images, but since this is the first time i am doing this, i ran into some problems.
From the PSD, i exported the shape as PNG and then converted it to SVG using some online converter.
Using CSS, i applied the mask to the image, like bellow, and in Chrome and Safari it works properly, but on Firefox it doesnt (i am guessing on IE too).
<style>
.mask {
-webkit-mask-box-image: url('http://imgh.us/mask_1.svg');
mask-border: url('http://imgh.us/mask_1.svg');
}
</style>
<img src="http://www.record-lrc.co.uk/Downloads/Cinnabar%20-%20Tyria%20jacobaeae[18042011].jpg" class="mask">
You can see the Fiddle here https://jsfiddle.net/f5tzv9Lr/2/ (be sure to use Chrome).
Can anybody suggest something or let me know what am i doing wrong?
UPDATE: From what i see, Mozilla has its own attribute, mask (https://developer.mozilla.org/en-US/docs/Web/CSS/mask), but it isnt working, at least in my case

Using CSS to transition the fill property of an SVG path on hover

I'm including an SVG image file on my page within an object tag, like this:
<object type="image/svg+xml" data="linkto/image.svg">
<!-- fallback image in CSS -->
</object>
The image in question is a world map, i want to transition the fill property when the mouse hovers over a group, in this case I've grouped my SVG by continent, so South America looks something like this:
<g id="south_america">
<path fill="#FAFAFA" d="(edited for brevity)"/>
</g>
I can get the fill property to change on hover by using the following CSS at the top of my SVG document:
<style>
#south_america path {
transition: fill .4s ease;
}
#south_america:hover path {
fill:white;
}
</style>
But I can't get the fill colour to fade in with a CSS transition, the colour just changes instantly, can anyone shed light on this please?
In order to transition/fade, CSS needs a starting value and an ending value.
Because you set the color for the path using the SVG attribute fill="#FAFAFA", CSS doesn't process it and the transition doesn't fade.
Instead if you use CSS to set the color, the transition will behave as expected
So all I had to do to make the transition work is give the #europe a starting fill to transition from.
path { transition: fill .4s ease; }
/* set fill for before and for during hover */
#europe path { fill: red; }
#europe:hover path { fill: white; }
Here's a working JSFiddle.
Or, doing it inline can be more convenient (style=""):
<path style="fill: #FAFAFA;" d="..."/>
Just in order for CSS to do your fading, it needs to handle the start and end values in CSS/inline style (as opposed to using the SVG fill= attribute).
Note that to style an SVG via CSS from within an HTML document, the SVG has to be embedded within the HTML of the page, i.e. it doesn't work by embedding it via <object> or <img> in HTML or via background-image etc. in CSS.
When it's embedded within your HTML, you can then style all its elements like you style HTML elements using a CSS selector to match the element(s) you want to style and applying the appropriate styles to it. Besides fill there is a bunch of other SVG attributes, which are also CSS properties. A list of them can be found in the SVG specification or on MDN.
In order for a transition to work, both the start and the end value have to be defined in CSS. So, instead of defining the fill color via the fill attribute (fill="#FAFAFA"), it needs to be defined either via the style attribute, which looks like this:
<path style="fill: #FAFAFA;" d="..."/>
or via a CSS rule packed in a <style> element within the SVG:
<style type="text/css">
#south-america > path {
fill: #FAFAFA;
}
</style>
In both cases you can then transition the values via the CSS rule you mentioned.
Embedding the SVG within HTML has the advantage that you can do the styling from within the stylesheet you use for your HTML, so you can define styling that are shared between the HTML of your page and the embedded SVG.

CSS 3 gradients for styling SVG elements

Is it possible to use CSS3 gradients for styling fill property?
I know that SVG provides their own gradients. But the ideal solution for me would be:
.button{
fill:#960000;
fill: -webkit-gradient,linear,left bottom,left top,
color-stop(0.45, #37304C),color-stop(0.73, #534D6B));
fill: -moz-linear-gradient(center bottom,#37304C 45%,#534D6B 73%);
...
}
When I tried to use SVG gradients, I got stucked when I tried to extract style attribute to external stylesheet. It seemed that fill:url(#linearGradientXYZ) didn't work as the gradient was defined in .svg file.
No it's not yet possible to use CSS3 gradients for the fill property. The good news though is that it's being discussed by the CSS and SVG workgroups, and SVG.next will depend on CSS3 Image Values (which defines the CSS gradient syntax). See http://www.w3.org/2011/07/29-svg-minutes.html#item08.
Note that the base url for the fill:url(...) by default is the file that contains this rule. So if you want to move fill:url(#linearGradientXYZ) to an external stylesheet remember to add the full path to the file containing that gradient definition, eg. fill:url(../images/gradients.svg#linearGradientXYZ).

SVG for images in browsers with PNG fallback

I'm looking to use SVG versions of a company logo on a website. At present, all current versions of major browsers (IE, Safari, Chrome, Firefox, Opera) support SVG, so this doesn't seem crazy. However, old browsers are still out there, so I need to fall back to PNG support.
The obvious solution is to put the SVG content in an object tag like so (forgive the inline styles...):
<object data='logo.svg' style='height:3em' >
<img src='logo.png' style='height:3em' />
</object>
Which in theory should render the object if possible, or else render the img. However, Chrome doesn't like this and applies the height style to the object itself but not the SVG, so I end up with a little iframe-like box with scrollbars, showing a huge logo.
Another solution would be to use the PNG as the img source, and then swap it out at render time with the SVG source with javascript, if I think I'm running on a SVG-capable browser. This is not ideal because the PNG will still get downloaded, and I'm not confidant I can properly detect SVG support. Unfortunately, jQuery doesn't seem to have a SVG-detect feature.
Finally, since my website is deployed with ASP.NET, I could inspect the user agent string before serving the page, and specify the img source depending on whether I think it will support SVG. But this also has the potential problem that I am not confidant I can make the right call.
What is the preferred way of doing SVG for images?
This is an old question, but here is another solution:
Download a version of Modernizr that is trimmed down to just testing SVG (assuming that’s the only test you need).
Run the test. If it passes, put in the SVG. If it fails, put in the bitmap. Essentially:
if (!Modernizr.svg) {
$("#logo").css("background-image", "url(fallback.png)");
}
SVG is a perfect use case for Modernizr, because there is no simple native way to provide a fallback.
Note: The browser don't load both (png and svg) versions.
For the record: the only reason you would need a fallback for SVG these days if you have to support IE 8 and down, or older Android.
I wouldn't call it the preferred way, but if you want to pursue your second option this should detect SVG support (from Raphaël 1.5.2):
if(window.SVGAngle ||
document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") {
// supports SVG
else {
// no SVG
}
Raphaël uses this to determine if it should render using VML (IE) or SVG (everyone else).
Out of curiosity, why SVG for your logo? If you already have a PNG version, this seems like a lot of work.
To solve your problem w/resizing SVGs in the object tag:
Add "preserveAspectRatio" and "viewBox" attributes to the svg tag. Open the file in a text editor and find the tag. in that tag, add the following attributes:
preserveAspectRatio="xMinYMin meet" viewBox="0 0 {width} {height}"
Replace {width} and {height} with some defaults for the viewBox. I use the values from the "width" and "height" attributes of the SVG tag. Save the SVG and it should now scale as expected.
See: How do I scale a stubborn SVG embedded with the <object> tag?
The problem w/SVGs in the object tag, though is that they swallow the clicks.
SVG as background-image w/PNG fallback: http://www.broken-links.com/2010/06/14/using-svg-in-backgrounds-with-png-fallback/
My favorite is using the img tag and an onerror handler to change the src tag to a PNG.
Another good resource: http://www.schepers.cc/svg/blendups/embedding.html
The only thing you need is CSS. First you declare the fallback image as a background-image. Then you can use multiple backgrounds to add the SVG.
IE8 and below will ignore the second background-image-declaration, because the lacking support of multiple backgrounds.
By the way, I'm using the img element here, because a logo is content, not layout. Using background-images might appear to be wrong in this context, but I disagree. You get the best of the worlds: SVG logo, fallback for
HTML:
<a href="/" class="site-logo">
<!-- base64 encoded 1x1 px big transparent gif -->
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="company logo">
</a>
CSS (using multiple background images):
caniuse: multiple backgrounds
PNG for IE <9, FF <3.6, Opera <10.5
SVG for all the others supporting SVG
Android 2.x won't have a PNG or SVG, due to these versions actually supporting multiple backgrounds, but not SVG
There is only one HTTP request made for browsers supporting SVG
.site-logo > img {
/* Dimensions of your image need to be set */
width: 32px;
height: 32px;
/* Fallback for <IE9 */
background-image: url(logo.png);
/* multiple backgrounds are ignored by <IE9 */
background-image: url(logo.svg), none;
}
CSS (using linear gradients):
caniuse: CSS gradients
PNG for IE <10, FF <3.6, Safari <4.0, Opera <11.1, Opera Mini, Opera Mobile <11.1
SVG for all the others supporting SVG (if vendor-prefixes are specified)
Ignoring the old gradient syntax for webkit makes Android 2.x use the PNG fallback
.site-logo > img {
/* Dimensions of your image need to be set */
width: 32px;
height: 32px;
background: transparent url(logo.png) center center no-repeat;
background-image: -webkit-linear-gradient(transparent, transparent), url(logo.svg);
background-image: linear-gradient(transparent, transparent), url(logo.svg);
}
Try svg-web they have a number of different ways of displaying svg images including flash with automatic fallback.
The best method I have found including SVG as an HTML element (with fallback) is this one:
<svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 100 100" style="width: 100px; height: 100px; vertical-align: top;">
<image xlink:href="image.svg" src="fallback.png" width="100%" height="100%"/>
</svg>
Pros:
Provides fallback in every device/browser I have tested (IE6-IE11, Android 2.0+, IOS3-7)
Only one image is loaded for each tested browser (except IE9-IE11)
Externally loaded images allows image to be cached
Cons:
Unable to use as scaleable (responsive) image in IE9-IE11 (see this question)
IE9-IE11 loads both images
IOS3-4 (Mobile Safari) has SVG support but displays the PNG (since it lacks inline SVG support)
SVG file must not have height / width attributes (unsure about this, but have read about it somewhere and in my tests my SVG did not have them anyway)
Does not validate
Please provide comments with additional pros / cons you can think of. I know for one SVG's can appear pixeled in some browsers, but I was unable to test zooming in since using browserstack for emulation.
Source: http://lynn.ru/examples/svg/en.html

Resources