I'm trying to reference SVG filters from CSS. Both are external.
It works fine when the SVG filter defs are inline but does not work when in external file.
I do not want the SVG inline to avoid a bloated html file.
According to this link, it should work if the svg comes from the "same origins" as the html. I'm not clear what "same origins" means.
My directory structure is:
index.html
\css
I tried all these without success:
putting the svg file on root with index
as well as in the css directory
using path url(css/test.svg#LightItUp);
putting the css inline like so: #LightItUp {filter:url(css/test.svg#LightItUp);}
The svg content:
<svg width="500" height="262" viewBox="0 0 200 150" >
<defs>
<filter id="LightItUp" filterUnits="userSpaceOnUse" x="0" y="0" width="400" height="420">
<!-- Apply a uniform blur of the
alpha channel -->
<feGaussianBlur in="SourceAlpha"
stdDeviation="3" result="blur"/>
</filter>
</defs>
</svg>
The css content:
.logo { filter: url(test.svg#LightItUp); }
Any help will be appreciated
Add it similar to a normal image
<object data="your.svg" type="image/svg+xml">
<img src="yourfallback.jpg" />
</object>
Related
Is there a way to fix the HTML validation error? While keeping using the SVG as the source code of the <img> tag?
Error: Bad value data:image/svg+xml;utf8,<svg
xmlns='http://www.w3.org/2000/svg' height='10px' width='20px'></svg>
for attribute src on element`
My source code:
<img alt="homepage" src="data:image/svg+xml;utf8,<svg
xmlns='http://www.w3.org/2000/svg' height='10px' width='20px'></svg>"
/>
To use an SVG as a data URI within an <img> element, the SVG code needs to be escaped:
<img alt="homepage" src="data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='10px' width='20px'%3E%3C/svg%3E">
There are several free tools for doing this, such as URL-encoder for SVG.
If you want a non-interactive svg, use with script fallbacks to png version (for older IE and android < 3). One clean and simple way to do that:
<img src="your.svg" onerror="this.src='your.png'">
your.svg being the path to your svg.
This will behave much like a GIF image, and if your browser supports declarative animations (SMIL) then those will play.
If you want an interactive svg, use either <iframe> or <object>.
If you need to provide older browsers the ability to use an svg plugin, then use <embed>.
For svg in css background-image and similar properties, modernizr is one choice for switching to fallback images, another is depending on multiple backgrounds to do it automatically:
div {
background-image: url(fallback.png);
background-image: url(your.svg), none;
}
An additional good read is this blogpost on svg fallbacks.
For inline SVG; <svg> tags can be inserted as <svg> elements directly into the HTML and not part of the <img> tag. As it is inline SVG the <img> tag is pretty redundant as all the required parameters can be held inside the <SVG>.
Read about it here
Example:
<html>
<head>
<title>SVG Demo</title>
</head>
<body>
<svg
viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice"
style="width:35%; height:35%; position:absolute; top:0; left:0; z-index:-1;">
<linearGradient id="gradient">
<stop class="begin" offset="0%"/>
<stop class="end" offset="100%"/>
</linearGradient>
<rect x="0" y="0" width="100" height="100" style="fill:#cc9966;" />
<circle cx="50" cy="50" r="30" style="fill:#f9f333;" />
</svg>
</body>
</html>
I am new svg learner and try to animate svg file with external style sheet but fail fail to style my object 'Cube'.
[index.html file]
<head>
<link rel="stylesheet" type="text/css" href="cube.css">
</head>
<body>
<img src="cube-motion.svg" height="350px" />
<div class="logo">
<h1>SVG Cube Animation</h>
</div>
[cube-motion.svg file]
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="cube.css" ?>
<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"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">
<g>
<polygon id="l1" class="st0" points="105.3,92.7 86.3,103.3 67.3,92.9 67.1,71.9 86,61.2 105.1,71.6 "/>
<polyline id="l2" class="st1" points="67.1,71.9 86.2,82.5 86.3,103.3 67.1,93.1 66.9,71.9 "/>
<animateTransform
attributeName="transform"
type="translate"
from="0 0"
to="0 75"
begin="0s"
dur="3s"
repeatCount="indefinite"
/>
</g>
</svg>
[external stylesheet file cube.css]
.st0 {
fill:#FF00FF;
stroke:#000000;
stroke-miterlimit:10;
}
.st1 {
fill:#23D83C;
stroke:#000000;
stroke-miterlimit:10;
}
.logo {
position: absolute;
left: 400;
top: 150;
}
You are on the right track with the inclusion of the external stylesheet inside the SVG:
<?xml-stylesheet type="text/css" href="cube.css" ?>
The reason it doesn't work is because the SVG is loaded in the HTML as an <img> which - rightfully - does not allow additional external assets to be processed.
If you're adamant on having the CSS from an external file, you have two options, either embed the SVG inside the html or use <object data=file.svg type=image/xml+svg></object>.
Depending on your use case, you basically have three ways to use CSS for styling:
<img src="my.svg">
Images are not interactive and are not allowed to load any other assets within themselves. Simple presentation of the referenced image file only.
It does allow to use CSS, but only from a <style>-element inside the SVG.
<object data="my.svg" type="image/svg+xml"></object>
Objects can do more than images, such as loading additional assets and even include isolated (within the loaded SVG) interactions (e.g. the CSS :hover-pseudoclass)
Loading an external CSS file is done as you have it in the example code, the <?xml-stylesheet...?>-instruction goes before the <svg>-tag
<svg...>...</svg>
Fully embedded in the HTML document, this is allows for full integration within the page (this may have benefits on the interaction side and downsides on the CSS side, as you'll then have to take style isolation into consideration), but also the least re-usable as you'd basically have to repeat the entire SVG, which doesn't matter if used once on a page.
Note that in order to embed the SVG inside the HTML document, you cannot put any of the SVG doctype and/or xml declarations in the HTML (<?xml...?>, <!DOCTYPE svg...> and <?xml-stylesheet...?>).
With embedded SVG, you can simply import (or inline) the style using the usual HTML <link> or <style> nodes, where the <style> element may also still be inside the <svg>-element.
Here's a quick sample of the difference between <img> and <object>
I have an SVG image with an illustration of a cloud.
The cloud is going to be used in several weather icons. I have another SVG file that embeds the cloud illustration and adds another graphical element, a circle.
Now, this main SVG file shows up fine when I open it directly in the browser:
However, when I use the file as a background-image, the cloud is not rendered:
Here's a JSFiddle.
What the heck?
It shouldn't be a relative path issue because the image shows up fine when I call the main SVG in the browser (and I tried using an absolute path to no avail)
It's not a clipping issue - if you change the background-size property in the JSFiddle, you'll see the entire image area is rendered, just without the cloud.
The cloud was generated by Adobe Illustrator and not optimized yet, but seems to look ok.
This is the main SVG's markup:
<svg width="100%" height="100%" viewBox="0 0 200 200" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="0" cy="-0" r="30" style="fill:red" />
<image x="12" y="12" width="20" height="40" xlink:href="elements/cloud.svg" />
</svg>
What am I doing wrong?
I've tested this in Safari 9.1.2 and latest Chrome on OS X, with the same result.
All SVGs that are inserted as images (through the img tag or as a background-image) cannot reference external files. So if you have an external CSS stylesheet, a custom font, or as in your case an external image, it won't work.
The solution would be to embed the image data within the xlink:href attribute:
<svg width="100%" height="100%" viewBox="0 0 200 200" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="0" cy="-0" r="30" style="fill:red" />
<image x="12" y="12" width="20" height="40" xlink:href="data:image/svg+xml,%0A%3Csvg%20id%3D%22Ebene_1%22%20data-name%3D%22Ebene%201%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20viewBox%3D%220%200%20284%20179%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3Anone%3B%7D.cls-2%7Bclip-path%3Aurl(%23clip-path)%3B%7D.cls-3%7Bfill%3A%23508f9e%3B%7D%3C%2Fstyle%3E%3CclipPath%20id%3D%22clip-path%22%20transform%3D%22translate(-278.44%20-208.09)%22%3E%3Crect%20class%3D%22cls-1%22%20x%3D%22279.44%22%20y%3D%22207.09%22%20width%3D%22284%22%20height%3D%22179%22%2F%3E%3C%2FclipPath%3E%3C%2Fdefs%3E%3Ctitle%3Ecloud%3C%2Ftitle%3E%3Cg%20class%3D%22cls-2%22%3E%3Cg%20id%3D%22TK6tin%22%3E%3Cpath%20class%3D%22cls-3%22%20d%3D%22M562.44%2C302.09c-4.19%2C9-7.71%2C18.44-13.39%2C26.63-9.1%2C13.12-21.26%2C22.65-35.52%2C30.06C497.65%2C367%2C481%2C372.3%2C463.34%2C373.68c-17%2C1.33-32.1-3.68-43.58-16.9-3-3.43-4.87-2.72-7.56-.06-6%2C5.92-11.9%2C11.83-19.1%2C16.52-9.22%2C6-19.37%2C9.45-29.58%2C13a4.17%2C4.17%2C0%2C0%2C0-1.09.89h-19c-7.91-2.63-15.56-5.83-21.8-11.53a10%2C10%2C0%2C0%2C0-6.55-2.63c-15.38-1.29-32.37-10.18-35.09-28.87-0.38-2.61.39-5.62-1.56-8v-5c2.09-3.79%2C1.2-8.2%2C2.85-12.26%2C2.87-7.07%2C8.91-9.62%2C15-11.45%2C5.41-1.62%2C9.87-3%2C11.87-9%2C3.9-11.71%2C12.39-17.5%2C24.66-17.08%2C5.43%2C0.18%2C7.92-1.18%2C10.39-6.77%2C4.51-10.24%2C12-18.52%2C21.06-25.77A171.48%2C171.48%2C0%2C0%2C1%2C398.75%2C227c20.39-9.63%2C41.2-17.45%2C64.13-17.83%2C1%2C0%2C2%2C.11%2C2.55-1.06h7c2.35%2C2.26%2C5.3.64%2C7.93%2C1.21%2C13%2C2.81%2C25.88%2C6.08%2C37.28%2C13.42%2C8.3%2C5.35%2C17.12%2C10.07%2C23.36%2C18a94%2C94%2C0%2C0%2C1%2C10.57%2C17.12c4.56%2C9.4%2C9.31%2C18.73%2C10.86%2C29.24v15ZM318.12%2C365.24c1.49%2C0.13%2C1.71%2C1.24%2C2.29%2C2a37.42%2C37.42%2C0%2C0%2C0%2C25.1%2C14.71c15%2C2%2C28.63-2.48%2C41.61-9.82C397.41%2C366.3%2C405%2C357.4%2C413.92%2C350c2.08-1.74%2C3.65-2.89%2C5.66-.08%2C12.35%2C17.29%2C30.17%2C21.51%2C49.68%2C19a127.56%2C127.56%2C0%2C0%2C0%2C54.87-21c16.7-11.17%2C26.73-27.07%2C33.68-45.37%2C0.68-1.8.5-3.59%2C0.63-5.41%2C1.16-16.58-6.55-30.39-13.88-44.3a39.91%2C39.91%2C0%2C0%2C0-7.73-10.86c-13.58-12.69-28.91-22-47.27-26.37-15.43-3.68-30.69-3.42-46.1-.72-15.69%2C2.75-30.25%2C8.85-44.45%2C15.69-23.79%2C11.46-45.28%2C25.58-54.66%2C52.22a3.16%2C3.16%2C0%2C0%2C1-3.27%2C2.38c-3.81.17-7.6%2C0.73-11.42%2C1-9.24.54-15.85%2C4.7-17.71%2C13.68-1.27%2C6.13-4.13%2C9-9.56%2C10.64-1.3.39-2.6%2C0.42-3.85%2C0.75-5.69%2C1.52-11.51%2C3.66-13.65%2C9.54-4.64%2C12.77-2.74%2C26.7%2C6.27%2C37.43%2C6%2C7.19%2C14.75%2C9.64%2C23.74%2C10.93%2C0.84%2C0.12%2C1.74%2C1.26%2C2.8.06C317.92%2C368%2C316.87%2C366.61%2C318.12%2C365.24Z%22%20transform%3D%22translate(-278.44%20-208.09)%22%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" />
</svg>
Please follow the explanation in this link:
https://css-tricks.com/using-svg/
You need to enter the full svg code. you can get it from photoshop or online tools like this:
.background-img {
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30'><circle cx='15' cy='15' r='10' /></svg>") no-repeat;
height: 30px;
width: 30px;
}
Below code works on home page where "page URL" == "base URL"
but fails on any other page
<svg>
<filter id="blur">
<feGaussianBlur stdDeviation="5"></feGaussianBlur>
</filter>
<image id="svg-image" xmlns:href="http://x.com/image.jpg"
filter="url(#blur)">
</image>
</svg>
Is there a way to reference "only the filter" from an external svg file ?
eg:
1.External file #(http://localhost/somewhere/external.svg)
<svg>
<filter id="blur">
<feGaussianBlur stdDeviation="5"></feGaussianBlur>
</filter>
</svg>
2.HTML document #(http://localhost/elsewhere)
<svg>
<image id="svg-image" xmlns:href="http://x.com/image.jpg"
filter="url(/somewhere/external.svg#blur)">
</image>
</svg>
Using a filename in your url() like that should work. Especially if you are referencing the current file. That will fix your problem with <base>.
However not all browsers support pointing to another file (yet).
Incidentally, your xmlns:xlink attribute is wrong. That should be xlink:hef="".
Just Don't || !possible
(as suggested by #RobertLongson and #PaulLeBeau)
I wanted to write a logo in svg, but surprisingly found that I could not re-use objects defined in <defs>...</defs>. I tried them on Chrome.
Please see examples:
test1.html doesn't work, no rect was drawn.
<!DOCTTYPE html>
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="480" height="360">
<defs>
<rect id="helo" x="0" y="0" height="20" width="20" />
</defs>
<use xlink:href="#helo" />
</svg>
</body>
</html>
BUT test2.svg works.
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="480" height="360">
<defs>
<rect id="helo" x="0" y="0" height="20" width="20" />
</defs>
<use xlink:href="#helo" />
</svg>
What's needed to make the test1.html work?
Many thanks:)
It seems that this is a bug in Webkit:
Importing external SVG (with WebKit)
https://bugs.webkit.org/show_bug.cgi?id=12499
If you're going to create an SVG icon, I would make it in a separate .svg file and then add it into the HTML with the object tag. That would be better anyway since if you make changes to the SVG file and it will change all instance on your website.
The bug seems to have been fixed now however there is one important caveat here that when you are trying to re-use objects in the defs tag in SVG on a HTML page the xmlns:xlink="http://www.w3.org/1999/xlink" is important and must be added to the SVG tag. Without that the href isn't resolved.