How to render svg with cripEdges under IE11? - css

I'm trying to render svg lines. I can set shape-rendering to crispEdges under chrome, but it doesn't work with IE11. How can I do the same with IE11? Thanks!

Turns out I have to set the attribute of the svg element, not the "style" of it. I was setting it to
<line style="shape-rendering: crispEdges" />. It should be <line shape-rendering="crispEdges"/>

Related

dominant-baseline behaves differently in Firefox. Why?

I noticed that the SVG attribute dominant-baseline behaves different in Chrome and Firefox.
The vertical alignment is not exactly the same for dominant-baseline="hanging". In Firefox, the gap between the path and the text is slightly bigger than in Chrome.
In Chrome 76.0.3809.132
In Firefox 69.0.1
I already read dominant-baseline doesn't work in Firefox but it doesn't seem to apply here since the attribute is directly on the <text> element.
<svg viewBox="0 0 200 120" xmlns="http://www.w3.org/2000/svg">
<path d="M20,20 L180,20" stroke="grey" />
<text dominant-baseline="hanging" x="30" y="20">Hanging</text>
</svg>
Example taken from https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dominant-baseline.
I would expect the vertical alignment to be the same across browsers but it's not. Any idea why ?
I ran into this as well.
It seems it was a known bug in FireFox but has been fixed (in v82 Aug-2020 as much as I can see).
So it looks fine in latest FireFox (87.0):
Html code in Stackblitz
I ran into it because some test automation tools (eg. Percy) still using old firefox version.

SVG transform="rotate(180)" does not work in Safari 11

For some reason element
<svg width="1000" height="500" transform="rotate(180)">...</svg>
is shown as not rotated in Safari 11.
Chrome 63 renders it properly.
What's the problem?
Thanks!
In SVG 1.1 <svg> elements did not support transform attributes. In SVG 2 it is proposed that they should.
Chrome and Firefox implement this part of the SVG 2 specification, Safari does not yet do so and IE11 never will.
You can achieve the same result in browsers that do not support this SVG 2 feature either by replacing the <svg> element by a <g> element or by creating an <g> child element on the <svg> element and putting the transform on the <g> element.
Browsers allow you to use CSS on the SVG-elements, so an easy fix is to use the CSS transform instead.
<!-- ( works on all elements ) -->
<path style="transform:rotate(180deg)" />

Why is filter(drop-shadow) causing my SVG to disappear in Safari?

I am developing an app using D3.js. I was sidetracked for a while, and recently came back to it. Today I found that, though it worked fine in the past, the SVG map in the app no longer displays on mobile Safari (iOS 9.3.1) or desktop Safari (v9.1 (11601.5.17.1) ).
I extracted the SVG and a single style rule and put them on CodePen to illustrate what happens. In Chrome, this pen will look fine. In Safari, it will be completely blank.
https://codepen.io/Kirkman/pen/pyKzeX
If you inspect the DOM in Safari, you find that the paths are there, and they are the right shapes. They just seem invisible. Unchecking the style rules in the inspector causes the entire map to magically appear (without the drop shadow, obviously)
The style rule is very straightforward:
svg {
-webkit-filter: drop-shadow( 2px 2px 4px rgba(0,0,0,.4) );
filter: drop-shadow( 2px 2px 4px rgba(0,0,0,.4) );
}
Can anyone suggest why this isn't working? Did I do something wrong, or has something changed in Safari?
Probably is a little late, but just in case I will leave you my answer. I had the same problem with Safari and I figured out that this seems to be a Safari issue/bug. You can work around this bug just wrapping your SVG tag with another HTML tag like a div and apply to this element the drop-shadow filter as you did in your example.
Here you have your example modified with the wrapper element
https://codepen.io/mauromjg/pen/rLaqWG
<div class="svg-wrapper">
<svg>...</svg>
</div>
//CSS
.svg-wrapper {
-webkit-filter: drop-shadow( 2px 2px 4px rgba(0,0,0,.4) );
filter: drop-shadow( 2px 2px 4px rgba(0,0,0,.4) );
}
Hope that helps!
Browsers calculate things differently and for some reason Safari hates you. Lol.
However you should be using SVG Filters instead. They are much more reliable.
SOURCE - w3schools
<svg height="140" width="140">
<defs>
<filter id="f3" x="0" y="0" width="200%" height="200%">
<feOffset result="offOut" in="SourceAlpha" dx="20" dy="20" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs>
<rect width="90" height="90" stroke="green" stroke-width="3"
fill="yellow" filter="url(#f3)" />
</svg>
Hope that helps!
I had a similar issue with Safari: SVG objects such as lines would disappear as soon as a filter effect was applied. The same code worked fine in Chrome and Firefox. The code was part of an Angular app. It turns out the problem was triggered by Angular employing the "base" tag.
It appears that Safari applies the base tag to fragment names within embedded SVG images, whereas Chrome and Firefox do not. This code illustrates the issue:
<html>
<head>
<base href="/">
</head>
<body>
<svg>
<filter filterUnits="userSpaceOnUse" id="glow">
<feGaussianBlur stdDeviation="1.5"></feGaussianBlur>
</filter>
<line x2="99" y2="99" stroke="red" filter="url(#glow)"></line>
<line y1="99" x2="99" stroke="green" filter="url(/_display/#glow)"></line>
</svg>
</body>
</html>
On Safari, only the green line will show, whereas Chrome and Mozilla with show both red and green line.
jsfiddle demonstrating the problem
In my case, I was using an SVG Filter, so I couldn't really apply the CSS solution. Instead, I was able to get the SVG to show up by applying a CSS transformation via Javascript after the page loads. Here's an example in plain JS:
setTimeout(function(){
document.getElementById("svg-element").style.display = "block";
},10);
If you want to know if this will work, see if the SVG shows up after you resize the browser or modify a CSS style rule using the inspector.
I also had loading indicator never stopping to rotate when this happened. Also when SVG with a style tag which set the shadow was opened in a separate window, there was no shadow. The solution was to use an SVG filter, and make sure to duplicate the element on which it was set, so that if the image is resized, the mobile safari would not pixelate it. E.g., as described here https://stackoverflow.com/a/52250105/1267201
I had the same issue in our Angular app since we use the <base> tag.
I added this to the controller:
$scope.basePath = window.location.href;
Then in the template I added the base path to the filter:
<g ng-attr-filter="url({{basePath}}#filter1_d)">
Hopefully this helps anyone who's using Angular. Check out this comment in Github for more information: https://github.com/airbnb/lottie-web/issues/360#issuecomment-320243980

How to scale an SVG with <image> tag fallback?

I am examining how to add external SVG files in a responsive manner, and fell for the SVG image tag trick, because it doesn't require JavaScript.
(The SVG has been 'washed' with scour, thus being stripped of height/width attributes, and viewBox being added, as recommended.)
The problem is that this technique seems to require a height and width attribute to work, on the image tag, which isn't responsive. Suggested syntax is:
<svg width="200px" height="100px">
<image xlink:href="logo.svg" src="logo.png" width="200px" height="100px"/>
</svg>
However, setting relative dimensions, like so:
<svg style="width:100%; height:100%">
<image xlink:href="logo.svg" src="logo.png" width="100%" height="100%"/>
</svg>
.. makes the SVG responsive, however renders the <image> element incorrectly (or, not as expected anyway). This can be fixed by adding preserveAspectRatio and viewBox attributes:
<svg style="width:100%; height:100%" preserveAspectRatio="xMidYMid meet" viewBox="0 0 200 100">
<image xlink:href="logo.svg" src="logo.png" width="100%" height="100%"/>
</svg>
Now everything works as expected in all major browsers, except that in IE9-11, the problem now lies with <svg> tag: it's not wrapped around the <image> tag.
Been playing around with various combinations, like omitting the <svg>'s height attribute, but to no avail.
Has anyone solved this without using JavaScript or conditional statements?
Note: Other methods to achieve the same is of course welcome (that is, responsive, external SVG file, working fallback, and without using JavaScript)
Note 2: The described method does not fallback gracefully in Safari on IOS 5 either.
I was working on the same issue today and ran across your question hoping for an answer.
Check out this code for the answer: http://jsfiddle.net/ECTBL/
The trick was having the right attributes in my SVG file i.e.
height="..."
width="..."
viewBox="..."
xml:space="preserve"
When I saved the file from illustrator, it was missing a height and width attributes in the SVG file.
Finally, you'll need the following CSS for it to work:
This is for a bug in webkit
svg { max-height: 100%; }
And of course, this makes the image stretch.
img { width: 100%; }

CSS SVG Mask for Firefox syntax issue

From the Mozilla Developer page, I am trying to recreate their SVG mask for CSS using the mask property.
CSS:
#canvasPreview {
mask: url(images/masks/circle2.svg#circleMask);
}
HTML:
<img id="canvasPreview" src="placehold.it/100x100"></img>
SVG:
<svg>
<mask id="circleMask" maskContentUnits="objectBoundingBox">
<circle cx="50" cy="50" r="50" fill="white" />
</mask>
</svg>
The SVG is externally referenced, not embedded like the MDN example. I have not tried embedding it, but I don't see why that would help. There are a few things I'm not clear on.
In the CSS, why am I putting the #circleMask identifier after the URL? Removing it does not make my code work and its inclusion was found on the MDN site specs, so I put it in there.
Is my SVG correct? Do I have to use the <mask> tag and id and objectBoundingBox attributes? What are they used for?
The part after the # in the URL must be the same as id of the mask. So you have that part right.
You can use objectBoundingBox if you want but then your content seems wrong. Your mask radius is 50 times the size of the object it is masking. Perhaps you meant 50%. Same with cx and cy.

Resources