I don't have any problems using clip-path with links to .svg files in Firefox, but Safari seemingly refuses to use them.
If you load my WIP page http://www.omakadesign.com in Firefox, you will see a butterfly pattern at the bottom of the menu, but if you load it in Safari, the menus are completely rectangular.
The relevant line appears in main.css (221) and looks like:
clip-path: url("../img/menu-news.svg#news-clip");
There seems to be very little information about clip-path and Safari, and not many questions about it on this site either (believe me I've looked). But then again, I can't even get the most basic inline svg example with clip-path to work even in Firefox, so perhaps there is something fundamental I'm missing on this topic?
(Also, though this is another subject, why these menus have both padding and margin on the bottom is a mystery to me since I zero them out using min-width...)
UPDATE:
I did a test and created a .svg with a mask tag in it and replaced the clip-path line that appears above with a css mask instead (still 221 if you want to try it with the Firefox Style Editor) and amazingly that still works in Firefox and Safari STILL skips over it:
mask: url("../img/menu-news-mask.svg#news-mask");
(Final update: Found the solution, but I'm not allowed to post it for another 5 hours... turns out, you have to use very, very specific SVG and use -webkit-mask for Safari.)
I found the solution. You have to use VERY SPECIFIC SVG code! Follow the example of this guy to the letter, and clipping will work in Safari too:
https://github.com/Modernizr/Modernizr/issues/213#issuecomment-1149691
(Sorry about posting my own answer for my own first question, but I was really desperate and I usually find that when you start asking others, that's when you stumble upon the solution...)
EDIT: Doesn't work in IE9, which I don't really care about, but just a heads up for those who do (the fallback is simply a plain rectangular menu for me which still works).
Thank you for having that link to Modernizr's github!
For a note on if you are clipping an image, what's important is the path has to be inside the clipPath.
On a side note, if you export your SVG Code from Illustrator. Just make sure to use the actual path instead of this:
<defs>
<path id="path" d="....">
</defs>
<clipPath id="clipping">
<use xlink:href="#path"/>
</clipPath>
<image clip-path=url(#clipping) ...>
to the actual path like this...
<clipPath id="clipping">
<path id="path" d="....">
</clipPath>
<image clip-path=url(#clipping) ...>
It will work in FF, Chrome, Safari, Opera and IE9 & 10.
Here's the jsfiddle
Edit
The original issue now I realized is a slightly different problem than what I had... Which is using the svg path to clip an image outside of the svg as an img tag. Unfortunately, IE, even 10 didn’t work when I tried the exact same method. Therefore, if you have have a single image, best is to embed the image inside the svg itself instead of clipping an img tag with the path. That worked for IE9&10 and then some..
For second part of your question (..why these menus have both padding and margin on the bottom..) :
main.css line 95
nav a {
background: none repeat scroll 0 0 #616161;
color: white;
display: block;
font: 12px/20px Lucida Sans Unicode,Lucida Grande,Lucida Sans;
margin-bottom: 10px;
padding: 15px 0;
text-align: center;
text-decoration: none;
}
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.
of I have an SVG object placed in a container. It has the following CSS on its class.
.container{
position: relative;
}
.svgObj{
position: absolute;
top: 0;
left: 0;
width: 2em;
height: 2em;
}
So, the problem is that the svg doesn't end up in 0:0 of the container but rather more like in 200px south of that.
The queer thing is that if I substiute the SVG tag for a DIV with the same class, it displays exactly where I want it to.
The problem is only apparent in IE (only tried 11, but likely there in earlier versions as well).
Well, fwiw the problem is also visible in Minori.
Works fine in Safari, Chrome, FF, Opera, well the bigs, except IE.
Any ideas are most welcome.
The HTML code looks like so
<div class="container">
<svg class="svgObject" data-x="0" data-y="0" data-text="My Obj" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<a id="h-72417" href="#">
<path d="M12 4a8 0z"></path>
<path d="M12 4a8 0-16z"></path>
</a>
</svg>
</div>
Never mind the path values, I shortened them here to save space. It shouldn't matter. The data attributes aren't relevant either. As stated, just switching SVG for DIV and adding a "hello" instead of the paths makes it work as expected.
Thanks.
I know this is an old question, but I came across it as I was searching for an answer to this issue myself. The solution that worked for me was to add preserveAspectRatio="xMinYMin meet" to the tag. This essentially makes the SVG responsive and shifts the contents to the top left of the SVG container.
I found the answer here: http://thenewcode.com/744/Make-SVG-Responsive
Thanks for answering this ceindeg, even after the fact.
For anyone else who's having this problem, an even better solution than the preserveAspectRatio attribute is to just simply make sure you have the width and height set inside the main SVG tag. Most browsers don't need them, but IE is different (of course).
Problem:
On page load, for a button, SVG which is being called in CSS background appears. On some event, I apply a class and to it call another SVG in CSS background. However that new SVG does not appear. If in debugger, I try to toggle the background, it then starts appearing.
What am I missing to get this working in IE11?
In Below picture, we are using <button> tag. On some event, the background SVG is changed.
CSS Code
.buttonIcons{
.svgicon-fields-add{ background-image:url('../assets/themes/svg/arrow_active.svg');
width: 16px;
height: 16px;
}
On disabled state, below is the CSS
.buttonIcons.disabled{
.svgicon-fields-add{ background-image:url('../assets/themes/svg/arrow_disabled.svg');
width: 16px;
height: 16px;
}
So initially all buttons are disabled, but if you see the first button needs to show active svg image, but it is not appearing. I can see it in IE11 console, and if in console, I toggle the property, it starts appearing.
The code works fine in Chrome
Thanks in advance for all the suggestions.
SVG file code
<?xml version="1.0" encoding="utf-8"?>
<svg width="16" height="16" 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"
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
<g>
<polygon fill="#00a6a0" points="7.6,1.6 6.7,2.4 12.3,8 6.7,13.6 7.6,14.4 14,8 "/>
<polygon fill="#00a6a0" points="2.6,1.6 1.7,2.4 7.3,8 1.7,13.6 2.6,14.4 9,8 "/>
</g>
</svg>
Based on the small number of views, this is an esoteric case, but I'm having the same problem. I've been on it for days. I also had a double problem where IE would not display the background on toggling the style in developer tools.
I thought it was initially a memory issue, where IE was allocating memory for the icon but not actually putting anything there.
So I applied the SVG as an xml-encoded string directly in the class itself. This solved one instance of an SVG background not appearing, but it didn't solve the problem mentioned here. Furthermore, this allowed me to see the toggle event you mentioned.
So I now believe that it is NOT a memory issue, but an issue with IE10/11's SVG rendering engine. The fact that this problem only happens with certain SVG's reinforces the idea that the IE rendering engine is crapping the bed with certain inputs. It also only happens when a CSS SVG background is being overridden by another class's SVG background.
I thus tried setting the object to display:none, then display:block in the hopes of forcing a re-render of the element. This didn't help. I destroyed the element then rebuilt it and appended it back where it was supposed to go. That didn't work.
To make things even more confusing, I was never able to replicate the problem locally. It would only ever manifest in certain environments, leading me to believe that it is a combination of the browser and some server settings. I have no idea what.
Regardless, the point is that IE is remarkably resilient it not re-rendering what it has rendered. And since the SVG engine is apparently separate from the DOM rendering engine, screwing around with the DOM will have no effect on what the SVG renderer has stored. You have to give it quantifiably different data to force the SVG engine to re-render.
The only solution I found was to have my two CSS classes then give IE different image data than what it found on page load.
.Class1 {
background-image: url("data:image/svg+xml,image-data...");
}
.Class2 {
background-image: url("data:image/svg+xml,image-data...");
}
These classes allow default page load states to be covered. Then when JS events change the appearance, instead of changing the class, assign an in-line CSS style with the XML-ified SVG image data with a slight difference. Anything will work. I used an extra space.
onclick="function(){
element.style.backgroundImage = "url(\"data:image/svg+xml,slightly-different-data...\")"
}
To reiterate, it is an SVG rendering problem that occurs on page load. You can force SVG to re-render the image by giving it slightly different data in-line. I would imagine that you could do the same thing with a third class that contains a reference to a slightly different SVG file from the initial one, but I didn't do this.
Make sure the SVG file has the width and height property.
And if there's a 'responsive' option in it, you should remove it.
The option resets the CSS width and height.
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'm trying to apply a Gaussian blur to an element which has some child nodes containing some content.
For Chrome I did in the applied style:
-webkit-filter: blur(2px);
Firefox doesn't support this. What firefox does support is applying SVG to elements. Knowing this I searched google for an example where they would explain how to use SVG to apply a gaussian blur to an element. I found this example with this demo.
I brewed up the following CSS:
#div-with-content{
-webkit-filter: blur(2px);
filter: url('#blur');
}
And put this into the corresponding HTML file:
<svg:svg>
<svg:filter id="blur">
<svg:feGaussianBlur stdDeviation="2"/>
</svg:filter>
</svg:svg>
But when I went to test the page I saw that div-with-content wasn't there anymore. It had disappeared. Everytime I remove the blur style from div-with-content it appears again.
Could anyone please help me out on this one, I've really tried everything within my knowledge.
I don't know if it's your apostrophes or your svg: but this version works perfectly in Firefox:
CSS:
#div-with-content{
filter: url("#blur");
}
HTML:
<svg>
<filter id="blur">
<feGaussianBlur stdDeviation="2"/>
</filter>
</svg>
<div id="div-with-content"> WOohooo</div>
If there is only text you would like to blur there is this little trick
p{
color: transparent;
text-shadow: 0 0 4px #222;
}
You can see it here how it works jsFiddle
edit
You can load from an external document, as long as "that document comes from the same origin as the HTML document to which it's applied".
Make sure the html page that has the svg effect is being passed in the URL argument along with the ID of the svg effect (for instance,
So, instead of
url('#filter-effect')
do
filter: url('index.html#filter-effect')
It wasn't obvious to me how this worked until I read #RobertLongon's comment, but it makes sense now. You can put all your SVGs in a single document and reference them from other html files.
-
Old Answer:
Mozilla Developer Network says:
You may specify SVG in styles either within the same document, or within an external style sheet.
...but they're full of it. Bug report?
use <style> instead of <link>
For reasons beyond my comprehension, if you declare the .blur class outside the html document, via <link>, your element will disappear while still occupying space. This is why the fiddles are working in other answers but implementation is not. JSFiddle appends your styles within the document using <style>. To avoid this behavior, you should instead declare the .blur class WITHIN the document, aka <style>...</style>
Also important:
NOTE: Namespacing is not valid in HTML5, leave off the "svg:" in tags for HTML-format documents.
Again, <style>, not <link>.
sources:
trial and error
mdn: Applying SVG effects to HTML content
I saw the same behavior with a filter I was trying to use. It turns out that I had also set the SVG where the filter was defined to display: none;. Once I removed that, the filters were available and the HTML elements they were applied to displayed properly.
This is probably 2 years too late, but Name calling the document didn't do it for me, but placing the style directly on the element like this worked perfectly:
<div class="imageblur" style="filter:url(#blur) ">