I have the following structure on my website, which should display an image within an svg tag.
<div class="wrapper">
<svg width="100%" height="100%">
<g class="image-map-container" transform="translate(143, 221.5) scale(1)"><image xlink:href="https://source.unsplash.com/random"></image></g>
</svg>
</div>
As you can probably imagine, I use this structure in combination with JS to scale and move the image within a set container.
This approach works great in Chrome, newer versions of Firefox and Safari 13.1, but in Safari 12.1 and in Firefox version 68 and downwards, the image isn't displayed at all.
What could be the reason for this?
I created the following snippet for reproduction purposes:
https://codepen.io/pasa/pen/RwaRrKm
Related
I have been developing a web page "game" on my PC based in HTML, SVG, and Javascript. It has a large image of the earth loaded into the SVG views through the SVG <image> tag. Testing on my PC this works with no problem, however recently I published it to a public web page (http://rbarryyoung.com/EarthOrbitalSimulator.html) and discovered that only the bottom right quarter of the SVG is rendering on both SVG views on my iPhone and iPad. Like this:
At first, I thought that it was just the image in the SVG viewports, but then I realized that the entire SVG viewport was black except for the lower-right quadrant. The SVG viewport is correctly fully sized, it just appears as if there is some black mask over 3/4s of it (or only 1/4 of it renders).
Here's what I think are the relevant HTML code lines, the containing Div tag for the first SVG view (line 67):
<div id="divSvg1"
style="position:relative; z-index:1; margin:15px;
top:100px;
width:640px; height:640px;
background-color:black;
float:left;"
>
The SVG tag (line 104):
<svg id="svgEa"
style="width:100%; height:100%;"
viewBox="-7500 -7500 15000 15000"
preserveAspectRatio="xMidYMid meet"
clip-path="url(#svgEaClip)"
transform="scale(1.0,1.0)"
version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- NOTE: All internal units are in KM (or %) -->
And the embedded Image tag (starting at line 160):
<g id="gEaAll" transform="scale(1.0,1.0)" >
<!-- ... -->
<g id="gEaSurfaceFacingBottom" class="eaSurfaceFacing">
<g id=gEarthImage>
<!-- ... -->
<image x="-6413" y="-6413" width="12826" height="12826" href="eosImages/globe-arctic 8bit.png" />
</g>
</g>
The second SVG view is a shadowed (<use..> tag), zoomed view of the first with the same problem.
I have tested this on my PC, on both screens in Chrome, Edge, and IE, where it works correctly on all of them. I have also tested this on my iPhone with both Safari and Edge and my iPad with Safari, Chrome, and Edge with the same failure on all of them. I have tried just a bare <img> tag of the PNG file outside of SVG and that works fine on these platforms.
I do not have any Android platforms to test with, so if anyone wants to try it and let me know, I can add those results here.
I have researched this, and though there's a bunch of stuff about iOS not rendering images, mostly those are a complete failure to render, rather than this very specific partial rendering, and much less specific stuff about SVG differences. Ultimately I didn't find anything that seemed to be the same problem.
To summarize then, my question is: what is causing this problem or what have I done wrong, and how can I fix it? (I do understand that I will need to have a different style/CSS layout for mobile, but I still need to know what needs to be changed to make this render correctly)
Add X and Y coordinates for your <rect />. In your case, your Clip-Path Rectangle is not in an exact coordinate.
Here is the code working for me
<clipPath>
<rect x="-7500px" y="-7500px" width="100%" height="100%" />
<cliPath>
replace this code with your <clipPath> on line 114 and 301.
Here is the Screenshot
Moreover here is a live demo that worked on my Mac Safari as well in windows Chrome, where I took one part of your code.
Update
Check the answer by #fussionweb.
Orignal answer:
You can try the -webkit- prefix before clip-path. It seems to be a safari issue related to clip-path.
I've got this inline SVG on my site
JSFiddle
Problem seems to be somewhere around this line.
<line
x1="25%" y1="-567"
x2="25%" y2="200%"
style="stroke-dasharray:6 11;"
transform="skewY(45)" />
On different versions of Firefox I see some glitches with missing or flicking parts of image. In chrome/edge everything is OK. Am I using some non-standard SVG stuff, or it's just some FF bug? And is there any workarounds?
My problem is the following : I try to display an image in a SVG section thanks to the <image> tag. The following code is an example.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
<image xlink:href="http://2.bp.blogspot.com/-auWhmIJyACw/TaHzOV8pN1I/AAAAAAAAAPY/2nGmNaJRaBs/s1600/roger-federer-widescreen-wallpaper-001.jpg" preserveAspectRatio="xMinYMin slice"></image>
</svg>
My problem is that it doesn't work on Safari and Firefox. It seems to come from the image tag which is not working. I don't know if it's a syntax or a xlink error.
There is a codepen if you want to make your tests : http://codepen.io/vavouweb/pen/VaMNqg
In SVG 1.1 the attributes width and height are mandatory for images.
The unfinished SVG 2 specification proposes that requirement be removed but only Chrome and possibly IE edge have implemented that suggestion at the moment as far as I know.
Safari 6.1.5 is not displaying a pattern in an SVG rectangle. I've finally simplified it down to this test case:
<html>
<head>
<style>
.patterned { fill: url("#myid") none; stroke:blue}
</style>
</head>
<body>
<svg width="2880" height="592">
<defs>
<pattern id="myid" patternunits="userSpaceOnUse" x="0" y="0" width="20" height="20">
<circle r="10" cx=12 cy=10 fill="purple">
</pattern>
</defs>
<rect class="patterned" height="27" width="58">
</svg>
</body>
</html>
Safari displays an empty blue outline, while Firefox and Chrome show polka-dots inside it. I have the same problem with the diagonal hatch pattern I'm using in the real thing.
I actually stumbled on a strange workaround that works for this snippet but not for the real thing: changing none to yellow after the url shows purple circles on a white/transparent background on all three browsers. Unfortunately, when I do that in my real application I get a yellow background and no pattern.
I now think my test case is a red herring; it fails for a different reason than my real web site fails to show the pattern. Safari can be made to produce the same result as the other browsers just by deleting the none after the URL. (Possibly a bug in Safari; see other answer.)
Unfortunately, that just means I failed to reduce my real problem to a small test case, because the real thing still doesn't work. After more experimentation, I found that I can break the corrected test case by adding a <base> element to the header. Presumably Safari doesn't resolve the url("#myid") correctly. (Also, Firefox and Chrome seem to resolve it differently if it appears in a file called styles/style.css; Chrome apparently uses the main document as the base, Firefox apparently looks for the {{defs}} in the style sheet.)
And yet Safari does still work if I serve the same the corrected test case as http://localhost:3000, so it's not as simple as file: vs. http:. It must be something else, somewhere in the huge complex web app I've taken over developing. I've now tried three times to isolate the problem by deleting elements until the pattern works (which is how I discovered that Firefox doesn't like the style being defined from another folder), but I've had no luck in isolating the problem with Safari.
I've given up for now and taken a different approach to get the visual effect the designer wants.
I begin to have a solution for my previous question Overlay SVG diagrams on google map.
But I have another (smaller) problem. I am using Firefox 3.5 and Safari 4 (on Mac), and when I am embedding SVG in a XHTML, I do not have at all the same result.
I can use the <object> or the <embedded> elements (but I think the last one is deprecated). I use them like that:
<div id="map_canvas" style="width: 900px; height: 900px">
<object data="test.svg" width="100%" height="100%" type="image/svg+xml"/>
</div>
And the size and the scale of the SVG is not the same with Firefox and Safari. In my SVG, the width, height and viewBox are defined.
Is there a way to have the same result with all the browsers (I don't care about IE that doesn't support SVG..., so "all the browsers" means at least the latest versions of Firefox, Opera and Safari) ?? Maybe something I forgot to define ?
EDIT: I also noticed that with <object>, the SVG is transparent with FF, but not transparent with Safari... :(
Is there a "standard" way to include a SVG ??
Thank you for your help
I only get different results in size between Firefox and Safari (on Windows) when a viewbox is defined in the svg.
A solution is to
set the width and height attribute in the object tag in html to absolute values (pixel)
set the width and height attribute in the svg file to relative values (e.g. 100%)
Then both FF and Safari show the same behaviour! You should try this, if this is applicable to your situation.
EDIT: Concerning your new questions:
- Transparency in Safari seems to be a bug: bugs Webkit
- Standard way for embedding: I don't think there is a standard way. you can use object, iframe, img or svg (inline declaration).
If you want it to work in every browser, you probably have to use browser sniffing and use object or img tags depending on the browser. Or you should try iframes. as they are supposed to have transparent backgrounds in safari and firefox. (but don't know about opera)
Like always in webdev browser support is the big problem, as you can see here: svg support (when you click the image, you can check for the svg features in detail)
If you are using svgweb for IE rendering of SVG you can achieve the same behaviour for most browsers. This assumes your SVG is not interactive (contains javascript), oterwise it needs to be embedded for any browser.
<html>
<head>
<!--[if IE]>--><script type="text/javascript" src="javascripts/svg/svg.js"></script><!--<![endif]-->
</head>
<body>
<div id="map_canvas" style="width: 900px; height: 900px">
<!--[if !IE]>--><img src="test.svg" width="900" height="900" /><!--<![endif]-->
<!--[if lt IE 9]><object src="test.svg" classid="image/svg+xml" width="900" height="900"></object><![endif]-->
<!--[if gte IE 9]><object data="test.svg" type="image/svg+xml" width="900" height="900"></object><![endif]-->
</div>
</body>
</html>