Chrome not rendering SVG referenced via <img> element - google-chrome
I am having issues with google chrome not rendering svg with an img element. This happens when refreshing the page and initial page load. I can get the image to show up by "Inspecting Element" then right clicking the svg file and opening the svg file in a new tab. The svg image will then be rendered on the original page.
<img src="../images/Aged-Brass.svg">
Totally at loss here as to what the issue is. The svg image renders fine in IE9 and FF just not in Chrome or Safari.
I have my MIME types set as well. (image/svg+xml)
EDIT:
Here is a simple html page that I built to help illustrate my issue.
<!DOCTYPE html>
<html>
<head>
<title>SVG Test</title>
<style>
#BackgroundImage{
background: url('../images/Aged-Brass.svg') no-repeat scroll left top;
width: 400px;
height: 600px;
}
#image_element {
width: 400px;
height: 600px;
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div id="image_element">
<img src="../images/Aged-Brass.svg">
</div>
<div id="BackgroundImage"></div>
</body>
</html>
As you can see I am trying to use an svg file in both an img element and in css as a background image. Neither work on the initial page load in chrome or safari. When I inspect element right click svg or click link to svg load in another window the svg file will render in original tab.
A simple and easy way; according to
https://css-tricks.com/forums/topic/svg-css-background-image-not-showing-in-chrome/
You have to open the .SVG file with a text editor (like notepad) and change
xlink:href="data:img/png;base64,
to:
xlink:href="data:image/png;base64,
it worked for me!
The svg-tag needs the namespace attribute xmlns:
<svg xmlns="http://www.w3.org/2000/svg"></svg>
i came here because i had the same problem,
when i inspect the element i can see the file, but on the site i can't (even when using localhost)
the answer to my problem was in saving the SVG file.
If you saved it from illustrator make sure to click 'embed' and not 'link'. as link will just refer to your local files rather than include the data (If i understand it correctly).
I read about it on the adobe website which has some other useful tips for exporting
http://www.adobe.com/inspire/2013/09/exporting-svg-illustrator.html
This worked for me, hope it was useful.
I came here because I had a similar problem, the image was not being rendered. What I found out was that the content type header of my testing server wasn't correct. I fixed it by adding the following to my .htaccess file:
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
Use <object> instead (of course, replace each URL with your own):
.BackgroundImage {
background: url('https://upload.wikimedia.org/wikipedia/commons/b/bd/Test.svg') no-repeat scroll left top;
width: 400px;
height: 600px;
}
<!DOCTYPE html>
<html>
<head>
<title>SVG Test</title>
</head>
<body>
<div id="ObjectTag">
<object type="image/svg+xml" data="https://upload.wikimedia.org/wikipedia/commons/b/bd/Test.svg" width="400" height="600">
Your browser does not support SVG.
</object>
</div>
<div class="BackgroundImage"></div>
</body>
</html>
I had a similar problem and the existing answers to this either weren't applicable, or worked but we couldn't use them for other reasons. So I had to figure out what Chrome disliked about our SVGs.
In our case in turned out to be that the id attribute of the symbol tag in the SVG file had a : in it, which Chrome didn't like. Soon as I removed the : it worked fine.
Bad:
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 72 72">
<defs>
<symbol id="ThisIDHasAColon:AndChromeDoesNotLikeIt">
...
</symbol>
</defs>
<use
....
xlink:href="#ThisIDHasAColon:AndChromeDoesNotLikeIt"
/>
</svg>
Good:
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 72 72">
<defs>
<symbol id="NoMoreColon">
...
</symbol>
</defs>
<use
....
xlink:href="#NoMoreColon"
/>
</svg>
Adding the width attribute to the [svg] tag (by editing the svg source XML) worked for me:
eg:
<!-- This didn't render -->
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
...
</svg>
<!-- This did -->
<svg version="1.1" baseProfile="full" width="1000" xmlns="http://www.w3.org/2000/svg">
...
</svg>
I had this problem when i exported images from figma. Check source code of svg, if you have colon : in ids like this: id="paint1_linear_23:318" it'll make you the problems with rendering in chrome.
Just remove all colons in ids.
Don't forget make the same with referring to this ids like this: fill="url(#paint1_linear_23:318)".
.svg image does not have it's initial height and width. Therefore it is not visible. You have to set it.
You can do either in-line or in css file:
In-line:
<img src="../images/Aged-Brass.svg" class="image" alt="logo" style="width: 100px; height: 50px;">
Css file:
<img src="../images/Aged-Brass.svg" class="image" alt="logo">
.image {
width: 100px;
height: 50px;
}
Just replace <img> tag to <object> tag for SVG image.
<object data="assets/twitter-wrap.svg" type="image/svg+xml"></object>
I had the same problem. This problem was solved when I checked the file type that was accepted and set in headers "Content-Type", "image/svg+xml":
response.setHeader("Content-Type", "image/svg+xml");
I was able to use your sample to create a test page, and it worked just fine. My assumption is that there is something wrong with your svg file. Can you paste that here as well? Here is the sample I used.
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<g>
<title>Layer 1</title>
<ellipse ry="30" rx="30" id="svg_1" cy="50" cx="50" stroke-width="5" stroke="#000000" fill="#FF0000"/>
</g>
</svg>
looks like a Chrome bug,
i did something else as i almost got crazy because of this...
using Chrom debugger if you change the css of the svg object it shows on the screen.
so what i did was:
1. check for screen size
2. listen to the "load" event of my SVG object
3. when the element is loaded i change its css using jQuery
4. it did the trick for me
if (jQuery(window).width() < 769) {
jQuery('object#mysvg-logo')[0].addEventListener('load', function() {
jQuery("object#mysvg-logo").css('width','181px');
}, true);
}
width: 180px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<object id="mysvg-logo" type="image/svg+xml" data="my svg logo url here">Your browser does not support SVG</object>
In my case this problem persisted when I created and saved the svg using Photoshop.
What helped, was opening the file using Illustrator and exporting the svg afterwards.
I also got the same issue with chrome, after adding DOCTYPE it works as expected
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
Before
<?xml version="1.0" encoding="iso-8859-1"?>
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="792px" height="792px" viewBox="0 0 792 792" style="enable-background:new 0 0 792 792;" xml:space="preserve">
<g fill="none" stroke="black" stroke-width="15">
......
......
.......
</g>
</svg>
After
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="792px" height="792px" viewBox="0 0 792 792" style="enable-background:new 0 0 792 792;" xml:space="preserve">
<g fill="none" stroke="black" stroke-width="15">
......
......
.......
</g>
</svg>
I exported my svg from Photoshop CC initially and had to manually add
version="1.1" into the <svg> tag
to get it showing on chrome.
Content type in the HTTP header from the server was the problem for me. I have a node.js server, added:
if( pageName.substring(pageName.lastIndexOf('.')) == '.svg' ) {
res.writeHead(200, { "Content-Type": "image/svg+xml" });
}
pageName is my local variable for what is requested.
My guess is this is a common problem! Am using the current version of Chrome (Mar 2020).
For me setting width / height to the img worked.
<asp:Image runat="server" ID="Icon" Style="max-width: 50px; max-height: 50px; position: relative;" />
I tried most of the solutions above, but didn't worked for me.
I used a svg sanitizr https://svg.enshrined.co.uk/ which worked.
I had a similar issue I think trying to set Sharepoint Icon to SVG and the file did not load properly (while Png did).
See thread: file-format-can-an-svg-file-be-used-as-a-site-icon-in-sharepoint-online
The reason for the issue is that the height and width flags are not set in the tag.
For instance, setting this works
I was able to fix the issue by:
Open SVG in a text editor (e.g. Notepad)
Include in the first SVG header code Width="80" Height="80" (perhaps can play with optimizing the size)
Save file and upload. IT WORKS!
So the first tag of my SVG looks like this
<svg height="80" width="80" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 114.60458 114.60458">
Had the same problem. If server is configured correctly and .htacces is not the answer, might want to look the svg source you are embedding. Mine were created with text editor, rendered well on Chrome&Safari inside html5 code, once embedded, nothing was visible.
Added correct version, dimensions etc to the svg code and works like a charm.
Also, all styles inline.
Ie
<svg version="1.1" baseProfile="full" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" rx="2" ry="2" width="24" height="24" style="fill:#fbc800;width:24px;height:24px;" />
</svg>
Be careful that you don't have transition css property for you svg images
I don't now why, but if you make: "transition: all ease 0.3s" for svg image on Chrome the images do not appear
e.g:
* {
transition: all ease 0.3s
}
Chrome do not render svg.
Remove any transition css property and try again
On problems try to open the images first with a program that is capable to read svg-images.
If that fails, then the svg-image is somehow corrupted.
I had that case and copied the svg-paths in a new svg-image and adjusted all details of the svg-tags.
I never tested the reason that it was not rendering but suppose that some invisible special signs caused the render-error. Getting sometimes files edited on Mac I had this issue in other context already.
I was having the same issue with an SVG image included via the IMG tag. It turned out for me that Chrome didn't like there being a blank line directly at the top of the file.
I removed the blank line and my SVG immediately started rendering.
I make sure that I add the Style of the Image. It worked for me
style= "width:320; height:240"
Lighttpd
My problem was that was missing a mime handler for svg files in lighttpd configuration file. Adding these to your lighttpd.conf could solve your problem:
mimetype.assign = (
".pdf" => "application/pdf",
".sig" => "application/pgp-signature",
".spl" => "application/futuresplash",
".class" => "application/octet-stream",
".ps" => "application/postscript",
".torrent" => "application/x-bittorrent",
".dvi" => "application/x-dvi",
".gz" => "application/x-gzip",
".pac" => "application/x-ns-proxy-autoconfig",
".swf" => "application/x-shockwave-flash",
".tar.gz" => "application/x-tgz",
".tgz" => "application/x-tgz",
".tar" => "application/x-tar",
".zip" => "application/zip",
".mp3" => "audio/mpeg",
".m3u" => "audio/x-mpegurl",
".wma" => "audio/x-ms-wma",
".wax" => "audio/x-ms-wax",
".ogg" => "application/ogg",
".wav" => "audio/x-wav",
".gif" => "image/gif",
".jpg" => "image/jpeg",
".jpeg" => "image/jpeg",
".png" => "image/png",
".svg" => "image/svg+xml",
".xbm" => "image/x-xbitmap",
".xpm" => "image/x-xpixmap",
".xwd" => "image/x-xwindowdump",
".css" => "text/css",
".html" => "text/html",
".htm" => "text/html",
".js" => "text/javascript",
".asc" => "text/plain",
".c" => "text/plain",
".cpp" => "text/plain",
".log" => "text/plain",
".conf" => "text/plain",
".text" => "text/plain",
".txt" => "text/plain",
".spec" => "text/plain",
".dtd" => "text/xml",
".xml" => "text/xml",
".mpeg" => "video/mpeg",
".mpg" => "video/mpeg",
".mov" => "video/quicktime",
".qt" => "video/quicktime",
".avi" => "video/x-msvideo",
".asf" => "video/x-ms-asf",
".asx" => "video/x-ms-asf",
".wmv" => "video/x-ms-wmv",
".bz2" => "application/x-bzip",
".tbz" => "application/x-bzip-compressed-tar",
".tar.bz2" => "application/x-bzip-compressed-tar",
".odt" => "application/vnd.oasis.opendocument.text",
".ods" => "application/vnd.oasis.opendocument.spreadsheet",
".odp" => "application/vnd.oasis.opendocument.presentation",
".odg" => "application/vnd.oasis.opendocument.graphics",
".odc" => "application/vnd.oasis.opendocument.chart",
".odf" => "application/vnd.oasis.opendocument.formula",
".odi" => "application/vnd.oasis.opendocument.image",
".odm" => "application/vnd.oasis.opendocument.text-master",
".ott" => "application/vnd.oasis.opendocument.text-template",
".ots" => "application/vnd.oasis.opendocument.spreadsheet-template",
".otp" => "application/vnd.oasis.opendocument.presentation-template",
".otg" => "application/vnd.oasis.opendocument.graphics-template",
".otc" => "application/vnd.oasis.opendocument.chart-template",
".otf" => "application/vnd.oasis.opendocument.formula-template",
".oti" => "application/vnd.oasis.opendocument.image-template",
".oth" => "application/vnd.oasis.opendocument.text-web",
# make the default mime type application/octet-stream.
"" => "application/octet-stream",
)
References
Alternative of AddType in lighthttpd
In my case it was not loading svg due to image tag's id containing _ (underscore) in it so I removed that from
<image id="image0_1166:0000"> to <image id="image0"> and it worked. And don't forget to remove the same here
<use xlink:href="#image0">
Related
SVG image not reacting to CSS colour changes [duplicate]
html <img src="logo.svg" alt="Logo" class="logo-img"> css .logo-img path { fill: #000; } The above svg loads and is natively fill: #fff but when I use the above css to try change it to black it doesn't change, this is my first time playing with SVG and I am not sure why it's not working.
You could set your SVG as a mask. That way setting a background-color would act as your fill color. HTML <div class="logo"></div> CSS .logo { background-color: red; -webkit-mask: url(logo.svg) no-repeat center; mask: url(logo.svg) no-repeat center; } JSFiddle: https://jsfiddle.net/KuhlTime/2j8exgcb/ MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/mask Please check whether your browser supports this feature: https://caniuse.com/#search=mask
If your goal is just to change the color of the logo, and you don't necessarily NEED to use CSS, then don't use javascript or jquery as was suggested by some previous answers. To precisely answer the original question, just: Open your logo.svg in a text editor. look for fill: #fff and replace it with fill: #000 For example, your logo.svg might look like this when opened in a text editor: <svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"> <path d="M0 0h24v24H0z" fill="none"/> <path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" fill="#fff"/> </svg> ... just change the fill and save.
Try pure CSS: .logo-img { /* to black */ filter: invert(1); /* or to blue */ filter: invert(0.5) sepia(1) saturate(5) hue-rotate(175deg); } more info in this article https://blog.union.io/code/2017/08/10/img-svg-fill/
If you want a dynamic color, do not want to use javascript and do not want an inline SVG, use a CSS variable. Works in Chrome, Firefox and Safari. edit: and Edge <svg> <use href="logo.svg" style="--color_fill: #000;"></use> </svg> In your SVG, replace any instances of style="fill: #000" with style="fill: var(--color_fill)".
You will first have to inject the SVG into the HTML DOM. There is an open source library called SVGInject that does this for you. It uses the onload attribute to trigger the injection. Here is a minimal example using SVGInject: <html> <head> <script src="svg-inject.min.js"></script> </head> <body> <img src="image.svg" onload="SVGInject(this)" /> </body> </html> After the image is loaded the onload="SVGInject(this) will trigger the injection and the <img> element will be replaced by the contents of the SVG file provided in the src attribute. It solves several issues with SVG injection: SVGs can be hidden until injection has finished. This is important if a style is already applied during load time, which would otherwise cause a brief "unstyled content flash". The <img> elements inject themselves automatically. If you add SVGs dynamically, you don't have to worry about calling the injection function again. A random string is added to each ID in the SVG to avoid having the same ID multiple times in the document if an SVG is injected more than once. SVGInject is plain Javascript and works with all browsers that support SVG. Disclaimer: I am the co-author of SVGInject
Edit your SVG file, add fill="currentColor" to svg tag and make sure to remove any other fill property from the file. For example: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 139.435269383854" id="img" fill="currentColor">... </svg> Note that currentColor is a keyword (not a fixed color in use). After that, you can change the color using CSS, by setting the color property of the element or from it's parent. Example: .div-with-svg-inside { color: red; } I forgot to say, you must insert the SVG this way: <svg> <use xlink:href='/assets/file.svg#img' href="/assets/file.svg#img"></use> </svg> if image is coming from some variable then <svg> <use [attr.xlink:href]="somevariable + '#img'" [attr.href]="somevariable + '#img'"></use> </svg> Note that `#img` is the id of the `svg` tag inside svg file. Also note `xlink:href` has been deprecated instead you should use `href` or use can use both to support older browser versions. Another way of doing it: [https://css-tricks.com/cascading-svg-fill-color/][1] [1]: https://css-tricks.com/cascading-svg-fill-color/
I suggest to select your color , and go to this pen https://codepen.io/sosuke/pen/Pjoqqp it will convert HEX to css filter eg:#64D7D6 equal filter: invert(88%) sepia(21%) saturate(935%) hue-rotate(123deg) brightness(85%) contrast(97%); the final snippet .filterit{ width:270px; filter: invert(88%) sepia(21%) saturate(935%) hue-rotate(123deg) brightness(85%) contrast(97%); } <img src="https://www.flaticon.com/svg/static/icons/svg/1389/1389029.svg" class="filterit />
This answer is based on answer https://stackoverflow.com/a/24933495/3890888 but with a plain JavaScript version of the script used there. You need to make the SVG to be an inline SVG. You can make use of this script, by adding a class svg to the image: /* * Replace all SVG images with inline SVG */ document.querySelectorAll('img.svg').forEach(function(img){ var imgID = img.id; var imgClass = img.className; var imgURL = img.src; fetch(imgURL).then(function(response) { return response.text(); }).then(function(text){ var parser = new DOMParser(); var xmlDoc = parser.parseFromString(text, "text/xml"); // Get the SVG tag, ignore the rest var svg = xmlDoc.getElementsByTagName('svg')[0]; // Add replaced image's ID to the new SVG if(typeof imgID !== 'undefined') { svg.setAttribute('id', imgID); } // Add replaced image's classes to the new SVG if(typeof imgClass !== 'undefined') { svg.setAttribute('class', imgClass+' replaced-svg'); } // Remove any invalid XML tags as per http://validator.w3.org svg.removeAttribute('xmlns:a'); // Check if the viewport is set, if the viewport is not set the SVG wont't scale. if(!svg.getAttribute('viewBox') && svg.getAttribute('height') && svg.getAttribute('width')) { svg.setAttribute('viewBox', '0 0 ' + svg.getAttribute('height') + ' ' + svg.getAttribute('width')) } // Replace image with new SVG img.parentNode.replaceChild(svg, img); }); }); And then, now if you do: .logo-img path { fill: #000; } Or may be: .logo-img path { background-color: #000; } JSFiddle: http://jsfiddle.net/erxu0dzz/1/
Use filters to transform to any color. I recently found this solution, and hope somebody might be able to use it. Since the solution uses filters, it can be used with any type of image. Not just svg. If you have a single-color image that you just want to change the color of, you can do this with the help of some filters. It works on multicolor images as well of course, but you can't target a specific color. Only the whole image. The filters came from the script proposed in How to transform black into any given color using only CSS filters If you want to change white to any color, you can adjust the invert value in each filter. .startAsBlack{ display: inline-block; width: 50px; height: 50px; background: black; } .black-green{ filter: invert(43%) sepia(96%) saturate(1237%) hue-rotate(88deg) brightness(128%) contrast(119%); } .black-red{ filter: invert(37%) sepia(93%) saturate(7471%) hue-rotate(356deg) brightness(91%) contrast(135%); } .black-blue{ filter: invert(12%) sepia(83%) saturate(5841%) hue-rotate(244deg) brightness(87%) contrast(153%); } .black-purple{ filter: invert(18%) sepia(98%) saturate(2657%) hue-rotate(289deg) brightness(121%) contrast(140%); } Black to any color: <br/> <div class="startAsBlack black-green"></div> <div class="startAsBlack black-red"></div> <div class="startAsBlack black-blue"></div> <div class="startAsBlack black-purple"></div>
Why not create a webfont with your svg image or images, import the webfont in the css and then just change the color of the glyph using the css color attribute? No javascript needed
Simple.. You can use this code: <svg class="logo"> <use xlink:href="../../static/icons/logo.svg#Capa_1"></use> </svg> First specify the path of svg and then write it's ID, In this case "Capa_1". You can get the ID of svg by opening it in any editor. In css: .logo { fill: red; }
The answer from #Praveen is solid. I couldn't get it to respond in my work, so I made a jquery hover function for it. CSS .svg path { transition:0.3s all !important; } JS / JQuery // code from above wrapped into a function replaceSVG(); // hover function // hover over an element, and find the SVG that you want to change $('.element').hover(function() { var el = $(this); var svg = el.find('svg path'); svg.attr('fill', '#CCC'); }, function() { var el = $(this); var svg = el.find('svg path'); svg.attr('fill', '#3A3A3A'); });
If you are just switching the image between the real color and the black-and-white, you can set one selector as: {filter:none;} and another as: {filter:grayscale(100%);}
To expand on #gringo answer, the Javascript method described in other answers works, but requires the user to download unnecessary image files, and IMO, it bloats your code. I think a better approach would be to to migrate all 1-color vector graphics to a webfont file. I've used Fort Awesome in the past, and it works great to combine your custom icons/images in SVG format, along with any 3rd party icons you may be using (Font Awesome, Bootstrap icons, etc.) into a single webfont file the user has to download. You can also customize it, so you only include the 3rd party icons you're using. This reduces the number of requests the page has to make, and you're overall page weight, especially if you're already including any 3rd party icons libraries. If you prefer a more dev oriented option, you could Google "npm svg webfont", and use one of the node modules that's most appropriate for your environment. Once, you've done either of those two options, then you could easily change the color via CSS, and most likely, you've sped up your site in the process.
Since SVG is basically code, you need just contents. I used PHP to obtain content, but you can use whatever you want. <?php $content = file_get_contents($pathToSVG); ?> Then, I've printed content "as is" inside a div container <div class="fill-class"><?php echo $content;?></div> To finnaly set rule to container's SVG childs on CSS .fill-class > svg { fill: orange; } I got this results with a material icon SVG: Mozilla Firefox 59.0.2 (64-bit) Linux Google Chrome66.0.3359.181 (Build oficial) (64 bits) Linux Opera 53.0.2907.37 Linux
The main problem in your case is that you are importing the svg from an <img> tag which will hide the SVG structure. You need to use the <svg> tag in conjunction with the <use> to get the desired effect. To make it work, you need to give an id to the path you want to use in the SVG file <path id='myName'...> to then be able to retrieve them from the <use xlink:href="#myName"/> tag. Try the snipped below. .icon { display: inline-block; width: 2em; height: 2em; transition: .5s; fill: currentColor; stroke-width: 5; } .icon:hover { fill: rgba(255,255,255,0); stroke: black; stroke-width: 2; } .red { color: red; } .blue { color: blue; } <svg width="0" height="0"> <defs> <path id="home" d="M100 59.375l-18.75-18.75v-28.125h-12.5v15.625l-18.75-18.75-50 50v3.125h12.5v31.25h31.25v-18.75h12.5v18.75h31.25v-31.25h12.5z"/> </svg> <span class="icon red"> <svg viewbox="0 0 100 100"> <use xlink:href="#home"/> </svg> </span> <span class="icon blue"> <svg viewbox="0 0 100 100"> <use xlink:href="#home"/> </svg> </span> Note that you can put any URL before the fragment # if you want to load the SVG from an external source (and not embed it into your HTML). Also, usually you do not specify the fill into the CSS. It's better to consider using fill:"currentColor" within the SVG itself. The corresponding element's CSS color value will then be used in place.
This might be helpful for people using PHP in combination with .svg images that they want to manipulate with CSS. You can't overwrite properties inside a img tag with CSS. But when the svg source code is embedded in the HTML you surely can. I like to resolve this issue with a require_once function where I include a .svg.php file. It's like importing an image but you can still overwrite styles with CSS! First include the svg file: <?php require_once( '/assets/images/my-icon.svg.php' ); ?> And it includes this icon for example: <svg xmlns="http://www.w3.org/2000/svg" width="20.666" height="59.084" viewBox="0 0 20.666 59.084"><g transform="translate(-639.749 -3139)"><path d="M648.536,3173.876c0-2.875-1.725-3.8-3.471-3.8-1.683,0-3.49.9-3.49,3.8,0,3,1.786,3.8,3.49,3.8C646.811,3177.676,648.536,3176.769,648.536,3173.876Zm-3.471,2.341c-.883,0-1.437-.513-1.437-2.341,0-1.971.615-2.381,1.437-2.381.862,0,1.438.349,1.438,2.381,0,1.907-.616,2.339-1.438,2.339Z" fill="#142312"/><path d="M653.471,3170.076a1.565,1.565,0,0,0-1.416.9l-6.558,13.888h1.2a1.565,1.565,0,0,0,1.416-.9l6.559-13.887Z" fill="#142312"/><path d="M655.107,3177.263c-1.684,0-3.471.9-3.471,3.8,0,3,1.766,3.8,3.471,3.8,1.745,0,3.49-.9,3.49-3.8C658.6,3178.186,656.851,3177.263,655.107,3177.263Zm0,6.139c-.884,0-1.438-.514-1.438-2.34,0-1.972.617-2.381,1.438-2.381.862,0,1.437.349,1.437,2.381,0,1.909-.616,2.34-1.437,2.34Z" fill="#142312"/><path d="M656.263,3159.023l-1.49-14.063a1.35,1.35,0,0,0,.329-.293,1.319,1.319,0,0,0,.268-1.123l-.753-3.49a1.328,1.328,0,0,0-1.306-1.054h-6.448a1.336,1.336,0,0,0-1.311,1.068l-.71,3.493a1.344,1.344,0,0,0,.276,1.112,1.532,1.532,0,0,0,.283.262l-1.489,14.087c-1.7,1.727-4.153,4.871-4.153,8.638v28.924a1.339,1.339,0,0,0,1.168,1.49,1.357,1.357,0,0,0,.17.01h17.981a1.366,1.366,0,0,0,1.337-1.366v-29.059C660.414,3163.893,657.963,3160.749,656.263,3159.023Zm-8.307-17.349h4.274l.176.815H647.79Zm9.785,43.634v10.1H642.434v-17.253a4.728,4.728,0,0,1-2.028-4.284,4.661,4.661,0,0,1,2.028-4.215v-2c0-3.162,2.581-5.986,3.687-7.059a1.356,1.356,0,0,0,.4-.819l1.542-14.614H652.1l1.545,14.618a1.362,1.362,0,0,0,.4.819c1.109,1.072,3.688,3.9,3.688,7.059v9.153a5.457,5.457,0,0,1,0,8.5Z" fill="#142312"/></g></svg> Now we can easily change the fill color like this with CSS: svg path { fill: blue; } I first tried to solve this problem with file_get_contents() but the solution above is much faster.
open the svg icon in your code editor and add a class after the path tag: <path class'colorToChange' ... You can add class to svg and change the color like this: codepen
Know this is an old question but recently we came across the same issue, and we solved it from the server side. This is a php specific answer but I am positive that other envs have something similar. instead of using the img tag you render the svg as svg from the get-go. public static function print_svg($file){ $iconfile = new \DOMDocument(); $iconfile->load($file); $tag = $iconfile->saveHTML($iconfile->getElementsByTagName('svg')[0]); return $tag; } now when you render the file you will get complete inline svg
For me, my svgs looked different when having them as img and svg. So my solution converts the img to csv, changes styles internally and back to img (although it requires a bit more work), I believe "blob" also has better compatibility than the upvoted answer using "mask". let img = yourimgs[0]; if (img.src.includes(".svg")) { var ajax = new XMLHttpRequest(); ajax.open("GET", img.src, true); ajax.send(); ajax.onload = function (e) { svg = e.target.responseText; svgText = ""; //change your svg-string as youd like, for example // replacing the hex color between "{fill:" and ";" idx = svg.indexOf("{fill:"); substr = svg.substr(idx + 6); str1 = svg.substr(0, idx + 6); str2 = substr.substr(substr.indexOf(";")); svgText = str1 + "#ff0000" + str2; let blob = new Blob([svgText], { type: "image/svg+xml" }); let url = URL.createObjectURL(blob); let image = document.createElement("img"); image.src = url; image.addEventListener("load", () => URL.revokeObjectURL(url), { once: true, }); img.replaceWith(image); }; }
Simple JS Use following short function ImgToSvg which swap img to svg (including class list) <img src="logo.svg" onload="ImgToSvg(this)" class="logo-img"/> const ImgToSvg= async (img) => { const s = document.createElement('div'); s.innerHTML = await (await fetch(img.src)).text(); s.firstChild.classList = img.classList; img.replaceWith(s.firstChild) } .logo-img { fill: yellow; } <img onload="ImgToSvg(this)" class="logo-img" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSIyIiB5PSIyIiB3aWR0aD0iMjk2IiBoZWlnaHQ9IjI5NiIgc3R5bGU9InN0cm9rZTojNTU1NTU1O3N0cm9rZS13aWR0aDoyIi8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtc2l6ZT0iMTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGFsaWdubWVudC1iYXNlbGluZT0ibWlkZGxlIiBmb250LWZhbWlseT0ibW9ub3NwYWNlLCBzYW5zLXNlcmlmIiBmaWxsPSIjNTU1NTU1Ij4zMDAmIzIxNTszMDA8L3RleHQ+PC9zdmc+" /> <!-- in this snippet I use dataURI in img src to avoid CORS problems witch reading svg data from external source by js --> This is improvement of Waruyama answer by providing short js function
I wanted to change specific paths and/or colors only and even colorize paths differently. Also, in my case some CSS was applied to the IMG-tag directly, hence I wanted to let it be original IMG-element to not mess around with positioning and alignment. Thanks to inspiration from this answer: https://stackoverflow.com/a/43015413/1444589, this is what worked for me: let img = document.querySelector('img[class^="YourClassName"]'); let imgURL = img.src; fetch(imgURL) .then(response => response.text()) .then(text => { let parser = new DOMParser(); let xmlDoc = parser.parseFromString(text, 'text/xml'); let svg = xmlDoc.getElementsByTagName('svg')[0]; let paths = xmlDoc.getElementsByTagName('path'); // access individual path elements directly let leftShape = paths[0]; leftShape.setAttribute('fill', '#4F4F4F'); // or find specific color const pathsArr = Array.from(paths); let skirtShape = pathsArr.find(path => path.getAttribute('fill') === '#F038A5'); skirtShape.setAttribute('fill', '#0078D6'); // Replace old SVG with colorized SVG // positioning and alignment is left untouched let base64Str = btoa(new XMLSerializer().serializeToString(svg)); img.src = 'data:image/svg+xml;base64, ' + base64Str; });
Why not just using CSS's filter property to manipulate the color on :hover or whatever other state? I found it works over SVG images into img tags. At least, it's almost fully supported in 2020. It seams to me the simpliest solution. The only caveat is having to tweak the filter properties in order to find the target color. But you have also this very useful tool.
for that matters you have to use your SVG as an inline HTML. say here's your logo.svg code (when you open it on textEditor): Logo.SVG <svg width="139" height="100" xmlns="http://www.w3.org/2000/svg"> <!-- Note that I've Added Class Attribute 'logo-img' Here --> <g transform="translate(-22 -45)" fill="none" fill-rule="evenodd"> <path d="M158.023 48.118a7.625 7.625 0 01-.266 10.78l-88.11 83.875a7.625 7.625 0 01-10.995-.5l-33.89-38.712a7.625 7.625 0 0111.475-10.045l28.653 32.73 82.353-78.394a7.625 7.625 0 0110.78.266z" fill="#00000" /> </g> </svg> add your desired Class/ID to it (i've added 'logo-img'): Edited Svg <svg class="logo-img" width="139" height="100" xmlns="http://www.w3.org/2000/svg"> <!-- Note that I've Added Class Attribute 'logo-img' Here --> ... </svg> Now apply Your Css Rules: CSS .logo-img path { fill: #000; } Pro With this way you can animate on user's actions (hover, selected,...) Con Your HTML File would be a mess. Heres a Stack Snippet <style> body { display: flex; justify-content: center; } .logo-img path { transition: .5s all linear; } .logo-img path { fill: coral; } .logo-img:hover path{ fill: darkblue; } </style> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <svg class="logo-img" width="139" height="100" xmlns="http://www.w3.org/2000/svg"> <!-- Note that I've Added Class Attribute 'logo-img' Here --> <g transform="translate(-22 -45)" fill="none" fill-rule="evenodd"> <path d="M158.023 48.118a7.625 7.625 0 01-.266 10.78l-88.11 83.875a7.625 7.625 0 01-10.995-.5l-33.89-38.712a7.625 7.625 0 0111.475-10.045l28.653 32.73 82.353-78.394a7.625 7.625 0 0110.78.266z" fill="#00000" /> </g> </svg> </body> </html>
If your shape(s) are always one solid color and you have more than a couple, you can use Fontello and make a custom icon font with a whole series of your own custom SVG shapes. Then you can set/animate the size and color of all of them with CSS alone. For all the possible use cases for this question, this is an essential paradigm to consider. I've used it in many projects. In any case, if you haven't heard of Fontello, you need to find out about it. If you know of a similar solution that is better, I would love to know. Possible downfalls: Icon/shape fonts are known to mess with screen readers, so that may take some handling. Fontello can be finicky with importing shapes, and it may take some trial and error with authoring and exporting them. Avoid any and all grouping, and use only single non-nested compound shapes.
Directly to svg fill css will not work you can use as below <style> svg path { fill: red; } </style> <svg xmlns="http://www.w3.org/2000/svg" width="20.666" height="59.084" viewBox="0 0 20.666 59.084"><g transform="translate(-639.749 -3139)"><path d="M648.536,3173.876c0-2.875-1.725-3.8-3.471-3.8-1.683,0-3.49.9-3.49,3.8,0,3,1.786,3.8,3.49,3.8C646.811,3177.676,648.536,3176.769,648.536,3173.876Zm-3.471,2.341c-.883,0-1.437-.513-1.437-2.341,0-1.971.615-2.381,1.437-2.381.862,0,1.438.349,1.438,2.381,0,1.907-.616,2.339-1.438,2.339Z" fill="#142312"/><path d="M653.471,3170.076a1.565,1.565,0,0,0-1.416.9l-6.558,13.888h1.2a1.565,1.565,0,0,0,1.416-.9l6.559-13.887Z" fill="#142312"/><path d="M655.107,3177.263c-1.684,0-3.471.9-3.471,3.8,0,3,1.766,3.8,3.471,3.8,1.745,0,3.49-.9,3.49-3.8C658.6,3178.186,656.851,3177.263,655.107,3177.263Zm0,6.139c-.884,0-1.438-.514-1.438-2.34,0-1.972.617-2.381,1.438-2.381.862,0,1.437.349,1.437,2.381,0,1.909-.616,2.34-1.437,2.34Z" fill="#142312"/><path d="M656.263,3159.023l-1.49-14.063a1.35,1.35,0,0,0,.329-.293,1.319,1.319,0,0,0,.268-1.123l-.753-3.49a1.328,1.328,0,0,0-1.306-1.054h-6.448a1.336,1.336,0,0,0-1.311,1.068l-.71,3.493a1.344,1.344,0,0,0,.276,1.112,1.532,1.532,0,0,0,.283.262l-1.489,14.087c-1.7,1.727-4.153,4.871-4.153,8.638v28.924a1.339,1.339,0,0,0,1.168,1.49,1.357,1.357,0,0,0,.17.01h17.981a1.366,1.366,0,0,0,1.337-1.366v-29.059C660.414,3163.893,657.963,3160.749,656.263,3159.023Zm-8.307-17.349h4.274l.176.815H647.79Zm9.785,43.634v10.1H642.434v-17.253a4.728,4.728,0,0,1-2.028-4.284,4.661,4.661,0,0,1,2.028-4.215v-2c0-3.162,2.581-5.986,3.687-7.059a1.356,1.356,0,0,0,.4-.819l1.542-14.614H652.1l1.545,14.618a1.362,1.362,0,0,0,.4.819c1.109,1.072,3.688,3.9,3.688,7.059v9.153a5.457,5.457,0,0,1,0,8.5Z" fill="#142312"/></g></svg> This worked for me
Unable to override fill property on SVG icon using React
I have a bunch of icons I have exported from Figma and I would like to create a wrapper Component around those icons, using the benefit of <use> tag. So I created a SVG file with all the symbols in order to target them by their id. The problem is, I am not able to override the fill property on the reused icons. After a lot of reading, I know that I'm supposed to use CSS inheritance since the reused element is in the shadow DOM and its properties cannot be accessed as usual. Just for debugging purposes, I copy pasted the source code of one of those icons directly in the component (and not using the import mechanism), and surprisingly, it works. Here is the code : icon.svg <svg xmlns="http://www.w3.org/2000/svg"> <symbol id="ic"> <path fill="#000" d="M81,40.933c0-4.25-3-7.811-6.996-8.673c-0.922-5.312-3.588-10.178-7.623-13.844 c-2.459-2.239-5.326-3.913-8.408-4.981c-0.797-3.676-4.066-6.437-7.979-6.437c-3.908,0-7.184,2.764-7.979,6.442 c-3.078,1.065-5.939,2.741-8.396,4.977c-4.035,3.666-6.701,8.531-7.623,13.844C22.002,33.123,19,36.682,19,40.933 c0,2.617,1.145,4.965,2.957,6.589c0.047,0.195,0.119,0.389,0.225,0.568l26.004,43.873c0.383,0.646,1.072,1.04,1.824,1.04 c0.748,0,1.439-0.395,1.824-1.04L77.82,48.089c0.105-0.179,0.178-0.373,0.225-0.568C79.855,45.897,81,43.549,81,40.933z M49.994,11.235c2.164,0,3.928,1.762,3.928,3.93c0,2.165-1.764,3.929-3.928,3.929s-3.928-1.764-3.928-3.929 C46.066,12.997,47.83,11.235,49.994,11.235z M27.842,36.301c0.014,0,0.027,0,0.031,0c1.086,0,1.998-0.817,2.115-1.907 c0.762-7.592,5.641-13.791,12.303-16.535c1.119,3.184,4.146,5.475,7.703,5.475c3.561,0,6.588-2.293,7.707-5.48 c6.664,2.742,11.547,8.944,12.312,16.54c0.115,1.092,1.037,1.929,2.143,1.907c2.541,0.013,4.604,2.087,4.604,4.631 c0,1.684-0.914,3.148-2.266,3.958H25.508c-1.354-0.809-2.268-2.273-2.268-3.958C23.24,38.389,25.303,36.316,27.842,36.301z M50.01,86.723L27.73,49.13h44.541L50.01,86.723z"/> </symbol> </svg> LocalIcon.css .icon { width: 100px; height: 125px; } use.ic-1 { fill: skyblue; } use.ic-2 { fill: #FDC646; } svg path { fill: inherit; } LocalIcon.js import React, { FC } from 'react'; import Icons from '../../icons/ic.svg'; import './LocalIcon.css'; const LocalIcon = ({ name, color, size }) => ( // <svg fill={color} width={size} height={size}> // <use className="icon" xlinkHref={`${Icons}#Icon/Heart/Filled`}/> // </svg> <> <svg> <symbol id="ic"> <path fill="#000" d="M81,40..."/> </symbol> </svg> <svg className='icon' viewBox='0 0 100 125'> <use className='ic-1' href={`${Icons}#ic`} x='0' y='0' /> // This one is still black </svg> <svg className='icon' viewBox='0 0 100 125'> <use className='ic-2' href='#ic' x='0' y='0' /> // This one works </svg> </> ); Does someone have an idea about what am I doing wrong ? Is that somehow related to the way I import the file ? Thanks a lot for your help.
In order for your CSS rule to apply, you need to change any fill rule in your SVG code to fill:'inherit'. Otherwise, the SVG style will override your CSS style.
Apply styles to an imported SVG [duplicate]
This question already has answers here: How to apply a style to an embedded SVG? (6 answers) Closed 7 years ago. I have a database that outputs an object with an SVG referenced within it. Inside this SVG I've got an external style sheet and what I would like to do is reference the class of in this SVG imported style sheet so I can colour the icons appropriately. At the moment it doesn't appear to recognise the class of the object at all and I wondered if this was even possible? Alternatively, is there any way I could apply a dynamically named id or class to part of the svg code that's imported via object, which I could then reference using the stylesheet. Here is a snippet of the HTML: <object class="getFit" type="image/svg+xml" data="../images/well-being/imageurl"> Your browser does not support SVG</object> The SVG: <?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <?xml-stylesheet type="text/css" href="../../well#york/svg-health.css" ?> <svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="128px" height="128px" viewBox="0 0 128 128" xml:space="preserve"> <g id="_x31_28px_boxes"> <rect fill="none" width="128" height="128"/> </g> <g id="Production"> <g> <path d="M47.9005,68.2746l-7.8831,11.5446L19.607,81.4577c-8.0373,0.6451-7.0919,12.8251,0.9781,12.1809 l23.3208-1.8721c1.8405-0.1478,3.5156-1.12,4.5568-2.6449l6.9434-10.1685C51.7793,76.2057,48.8114,72.7493,47.9005,68.2746z"/> <path d="M111.0477,57.7956l-14.9185-2.9008C86.0095,31.5106,87.623,33.068,57.7699,25.3819 c-1.2517-0.3173-2.6302-0.0971-3.7574,0.7207L37.0909,38.3789c-3.719,2.6923-0.1874,8.4495,3.8984,6.3709l16.4271-8.357 l10.1408,2.6252c-3.2134,5.3099-0.6341,1.3988-13.1933,19.7913c-3.6807,6.4816-2.3874,11.5738,3.6894,16.2671l0.0034-0.005 c0.106,0.0745,16.7525,10.2843,16.7525,10.2843l-9.1826,24.4947c-2.8514,7.6054,8.6288,11.7947,11.4423,4.2895l10.9522-29.2146 c1.0273-2.7405-0.033-5.8246-2.5283-7.3541l-15.6026-9.5634l12.6636-17.919C82.588,50.1536,88.638,61.782,88.638,61.782 c0.6839,1.2147,1.9524,2.0668,3.4475,2.1532l18.0603,1.0444C114.6242,65.2435,115.4678,58.6551,111.0477,57.7956z"/> <path d="M94.179,31.8982c5.9954-1.2801,9.8316-7.1943,8.553-13.1839c-1.2356-5.8638-7.077-9.8554-13.1953-8.5549 c-5.9856,1.2878-9.8276,7.21-8.562,13.2012C82.2281,29.2015,88.0569,33.2142,94.179,31.8982z"/> </g> </g> </svg> My CSS: #charset "utf-8"; /* CSS Document */ .getFit path, object.getFit circle { fill:#ff5000; } .eatWell path, object.eatWell circle { fill:#009F14; } .feelGood path, object.feelGood circle { fill:#ffc200; }
When using object the content is confined to its document. How to apply external stylesheet to an embedded SVG? What you are trying to do is even more complicated. but it is possible. If each of your icons gets a css file then you can use javascript to add a stylesheet to your svg document when its loaded. var svgobject = document.getElementsByClassName(".getFit"); for (var i=0; i<svgObject.length; i++) var svgDoc = svgObject[i].contentDocument; var linkElm = svgDoc.createElementNS("http://www.w3.org/1999/xhtml", "link"); linkElm.setAttribute("href", "getFitStyle.css"); linkElm.setAttribute("type", "text/css"); linkElm.setAttribute("rel", "stylesheet"); svgDoc.getElementById("where-to-insert").appendChild(linkElm); }
SVG with USE tag not rendering
The DOM already includes an empty SVG tag (svg). When I try to dynamically append a USE tag of an existing SVG symbol (symbol) with an id (iconId): svg.empty(); svg[0].setAttribute('viewBox', symbol.getAttribute('viewBox')); svg.append('<use xlink:href="#' + iconId + '"></use>'); it no longer renders the SVG. In Chrome, it renders if I add: element.html(element.html()); or manually manipulate the viewBox attribute, but that's not a real solution and IE doesn't like it at all. It's worth mentioning that if I append SVG graphics directly, the element renders. What is happening here and why isn't the SVG drawing after appending the USE tag?
After all it was indeed a matter of namespaces. Specifically, SVG elements and attributes must be created and set using document.createElementNS and node.setAttributeNS. $(document).ready(function(evt) { var svgns = 'http://www.w3.org/2000/svg', xlinkns = 'http://www.w3.org/1999/xlink', use = document.createElementNS(svgns, 'use'); use.setAttributeNS(xlinkns, 'xlink:href', '#save'); document.getElementById('useSVG').appendChild(use); }); #svgStore { display: none; } #useSVG { width: 16px; height: 16px; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <svg style="display:none;" id="svgStore" style="display: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <symbol viewBox="0 0 16 16" id="save"><title>save</title> <g id="svgstore3748a955346b4a088bbdc55a22f56504_x31_6_13_"> <path style="fill-rule:evenodd;clip-rule:evenodd;" d="M9,4h2V2H9V4z M13,13H3v1h10V13z M13,11H3v1h10V11z M13,0H0v16h16V3L13,0z M3,1h9v4H3V1z M14,15H2V8h12V15z M13,9H3v1h10V9z"> </path> </g> </symbol> </svg> SVG use: <svg id="useSVG" xmlns="http://www.w3.org/2000/svg"></svg> Thanks to #RobertLongson and http://www.kevlindev.com/tutorials/basics/shapes/js_dom/ for directing to the answer.
Apply SVG Filter to HTML5 Canvas?
Objective: Apply CSS Filters to video using html5 and JavaScript. Contraints: The solution must be compatible with Internet Exporer 10 (for Windows 8). I am really making a Metro app. So Far: I have a <video> that I am pumping onto a <canvas>. I thought I would be able to apply CSS filters directly to this (e.g. invert or brightness) but it turns out those are not compatible with IE10. Thoughts: I am hoping for a way to apply SVG filters to the canvas. Is this possible? Do I need to copy the <canvas> to an <image> and apply the filters to that? Alternatively, should there be a way to wrap the canvas in a <foreignObject>? Thank you for all your help! Here is some code for those interested: filters.svg: <?xml version="1.0" standalone="no"?> <svg width="1" height="1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <filter id="blur"> <feGaussianBlur in="SourceGraphic" stdDeviation="2 3" /> </filter> </defs> </svg> style.css: .a { filter: url(filter.svg#blur); -ms-transform: matrix(-1, 0, 0, 1, 0, 0); } page.html: <div class="itemtemplate" data-win-control="WinJS.Binding.Template"> <canvas class="a" style="width: 180px;height:180px;margin-bottom: -5px;" data-win-bind="style.backgroundColor: bc; id: effectId" /> </div> The Following Code Works, albeit very slowly, to accomplish my goal. Thank you, Anthony! <html> <head> </head> <body> <svg id="svgroot" viewbox="0 0 800 800" width="800" height="800" preserveAspectRatio="xMidYMin"> <defs> <filter id="myHueRotate"> <feColorMatrix type="hueRotate" values="270"/> </filter> </defs> <image id="a" filter="url(#myHueRotate)" x="0" y="0" width="300" height="300" /> <image id="b" filter="url(#myHueRotate)" x="300" y="0" width="300" height="300" /> <image id="c" filter="url(#myHueRotate)" x="0" y="300" width="300" height="300" /> <image id="d" filter="url(#myHueRotate)" x="300" y="300" width="300" height="300" /> </svg> <canvas id="canvas" height="300" width="300"></canvas> <video id="vid" src="movie.m4v" height="300" width="300" style="display: none" autoplay/> <script> var ctx = document.getElementById('canvas').getContext('2d'); var img = new Image(); img.src = 'img.jpg'; img.onload = function(){ //ctx.drawImage(img,0,0); //var canvasImage = canvas.toDataURL("image/png"); //var svgImage = document.getElementById('a'); //svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", canvasImage); draw(); } img.load(); function draw(){ var ctx = document.getElementById('canvas').getContext('2d'); var vid = document.getElementById('vid') ctx.drawImage(vid,0,0,300,300); var canvasImage = canvas.toDataURL("image/png"); document.getElementById('a').setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", canvasImage); document.getElementById('b').setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", canvasImage); document.getElementById('c').setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", canvasImage); document.getElementById('d').setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", canvasImage); setTimeout(draw,40); } </script> </body> </html>
First, articles to read: moving-to-standards-based-web-graphics-in-ie10 Notice specifically the sections: Use SVG, not VML and Use CSS3, not DX Filters In that second section, they mention: DX Filters are not the same as SVG Filter Effects, though both use the CSS property name filter. Second article: Introduction to Filters and Transitions They give a specific example of how to use invert, but, assuming it is the way in IE, I can see why it wasn't easy to find and may or may not work in your case. But the css would be: #yourTargetElement { filter: DXImageTransform.Microsoft.BasicImage(invert=1); } They don't mention brightness, but they do mention several other filters and transitions, and that first article does mention using SVG. More details (hopefully helpful ones) at: SVG Filter Effects in IE10 This looks like part 1 of the key: A filter is applied to an SVG element via the filter attribute, in the form of filter="url(#filterId)", or it can be applied as a CSS property filter:url(#filterId) And this is part 2: There are 16 different filter primitives. Now, I believe the 16 they refer to are the full set for SVG, but knowing MS, it could also mean either: These are the 16 we support, or These are the 16 we've invented so as to continue our claim to make IE standards-compliant and SVG/MathML friendly, but making it harder than it would be in any other browser...because we can. Or, to quote Lily Tomlin: "We don't care, we don't have to...we're the phone company." But, assuming MS is finally realizing they need to catch up, reading further on the 16 primitive filters, supposedly you just have your embedded SVG, with the filters in the right place (defs) and call them via css. Here is one of their examples (slightly modified and simplified by me): HTML w/ Embedded SVG: <div id="svg_wrapper"> <svg xmlns="http://www.w3.org/2000/svg" id="svgroot" viewBox="0 0 800 533" preserveAspectRatio="xMidYMin"> <defs> <filter id="filtersPicture"> <feComposite operator="arithmetic" k1="0" k2="1" k3="0" k4="0" in="SourceGraphic" in2="SourceGraphic" result="inputTo_6"> </feComposite> <feColorMatrix type="saturate" id="filter_6" values="2" data-filterId="6"> </feColorMatrix> </filter> </svg> </div> CSS (They use JS to make it dynamic, so beware): <style type="text/css"> #yourTargetElement{ filter:url(#filtersPicture); } </style> The reason I caution on how "easy" they make it look is because they are adding the style via js and an interactive form (maybe you have the same thing in mind), but I imagine that runs the same risk as calling an element in a script before it is in the DOM, in that it can't find the filter and throws an error. So be sure if you want to keep it simple (non-dynamic) and things still aren't working, to try putting the filter/svg above the style (even if this causes a flicker).