SVG Size and Color - html

I've been looking at using SVGs on my site, I wish to color them via CSS, I've looked at some blogs which suggest using the object tag:
<object type="image/svg+xml" data="/static/test.svg">Your browser does not support SVG</object>
I'm now trying to do two things, colour the svg, I've tried using:
fill: red;
But no luck.
And size it, I've tried this on the object:
width="150px"
But no luck.

You have to use an <svg> object to make it possible. A good solution could be to use the iconic's SVGInjector so you can load it from another file and keep your code clean.

Related

Setting background color of SVG using CSS

First time posting here, so treat me gently. :)
I have an SVG image on my site which has a transparent background -
<img class="img-responsive center-block" src="images/pritchservices.svg" alt="Pritch Services Logo" />
Works beautifully on my site. However, due to the transparency, when that image loads in google image search results, due to the transparency, looks terrible.
I have an alternative image (using for fb Open Graph crawler) which is here -
Pritch Services Full Logo
In my crazy mind, this is what I had as a plan:
Redo the SVG in Illustrator to include the background color (as per the fb OPen Graph image) - this would then mean the image result in Google would be as expected
Have some CSS within my site to set the background color of the SVG to transparent, so it displays nicely (as it currently does on the site)
I am assuming I can't just put the SVG markup inline, as although this would give me what I wanted on the page, it wouldn't load the image AT ALL on google image search results?
Is this the way to go, if so, any suggestions on how to implement please; or is there an alternative solution I haven't thought of? Or am I just being too picky?!
Thanks in advance everyone...
You can't include an SVG via <img> and style it with CSS in your parent document.
You can't style the contents of an <img>, even if it is an SVG
CSS doesn't apply across document boundaries
You have a few options.
Include the version with a background in your page. And then hide it and replace it with the transparent-background version via CSS.
<div class="logo">
<img src="logo-with-background.svg" ... />
</div>
.logo img {
display: none;
}
.logo {
background-image: url(logo-without-background.svg);
}
Include the background version using <object> then use the DOM to find the background element and hide it.
var object = document.getElementById("myObject");
var svgDoc = myObject.contentDocument;
svgDoc.getElementById("bg").setAttribute("display", "none");
Apply a clipping path to the backgrounded version as #Obink suggests. It would work, but it is not the easiest solution though. And it won't work on older browsers that don't support clip paths.

SVG stacking causes distortions

I'm trying out the SVG stacking technique to enable multiple icons stacked in a single file, requiring only a single HTTP request from the browser. The technique is described pretty thoroughly here.
Basically the idea is that you put multiple SVG elements into a single SVG file, and use CSS styling to hide all icons, except for the icon you currently want to display. You select the icon you currently want to display using the CSS :target selector.
The technique works for me, except stacking multiple icons causes weird distortions in the displayed icon, even though all other icons are hidden.
In the example I'm working with, I simplified this to stacking only two icons: an US flag icon and an UK flag icon.
The (simplified) SVG file is:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg153" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="480" width="640" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<svg:style
xmlns:svg="http://www.w3.org/2000/svg" type="text/css">
.i { display: none; }
.i:target { display: block; }
</svg:style>
<svg:svg id="uk" xmlns:svg="http://www.w3.org/2000/svg" class = "i" height="480" width="640" version="1.1">
<!-- SVG elements to draw UK flag -->
</svg:svg>
<svg:svg id="us" xmlns:svg="http://www.w3.org/2000/svg" class = "i" height="480" width="640" version="1.1">
<!-- SVG elements to draw US flag -->
</svg:svg>
</svg>
Note that the CSS is embedded within the SVG file, in a <svg::style> element. The CSS is simply:
.i { display: none; }
.i:target { display: block; }
This way, any svg::svg element with class="i" is automatically invisible, unless we specifically target it in the SVG url. So this way, to display a US flag icon, I would use the following HTML snippet:
<img
src="flags.svg#us"
width="80"
height="60"
alt="SVG Stacked Image"
/>
And of course, to display the UK flag I would change it to src="flags.svg#uk"
Anyway, all of this works wonderfully... except for a strange image distortion which occurs in both Firefox and Chrome when I stack the images.
Here's a screenshot of the US flag when I remove the (hidden) UK flag from the SVG file:
As you can see, it looks fine.
But when I stack it in front of the UK flag, it looks like:
As you can see, the image becomes strangely distorted - it almost looks like what happens to a low-quality JPEG when you get a lot of "artifacts" in the compressed image.
So why exactly is this happening? The other images stacked with the US flag icon are all invisible, so why should they effect the visible icon at all?
I Googled around a lot looking for answers, and although there are definitely many issues and "gotchas" with the SVG stacking technique, they all relate to cross-browser compatibility. However, the technique works fine on most newer browsers up to and including IE9. Also, the distortion happens in both Firefox and Chrome, so this isn't likely to be some cross-browser issue, but rather something I'm doing wrong.
So, what is causing this weird distortion when I apply the SVG stacking technique?
No idea about stacking and target. But I know two simple methods.. may be those can help you out in an easier way.
When you have chosen different svg icons from net or even from computer but each icon is separate.
There is a website 'icomoon.io', where we can choose different icons from online libraries or your custom svg icons from your computer.
Open 'https://icomoon.io/app/'
Choose 'import icons' to upload custom icons from your computer.
At bottom of the page it has 'Add Icons From Library…' to choose icons from online libraries.
From 'select' tool (At Top) select multiple icons as you like.
After selecting multiple icons choose 'Generate SVG,PNG,PDF' button at bottom.
Then to combine all of them in a single file, click on 'settings icon' located just next to the 'Download' option in first button at bottom left.
Choose 'Include Tiles (CSS Sprite) from it.
Put appropriate margins and number of icons in a row as you like and then download the combine sprite with its xml code in demo.html and css definitions in style.css.
When you have already created single SVG file of multiple icons using 'AI' or any other software.
Just upload(import) that file to icomoon.io and click on 'Generate SVG,PNG,PDF' button and download the sprite xml file.
I tried with my own simple svgs and it works fine, no weird distortion happening. So my guess is it's your svgs for uk and us.
http://pastebin.com/dxVtTQKF

Manipulating external svg file style properties with CSS

I am trying to manipulate an external .svg file via CSS.
HTML
<body>
<div class="mysvg">
<img src="decho.svg" alt="decho" width="200px"></img>
</div>
</body>
CSS
div.mysvg img {
opacity: .3;
transition: opacity 1s linear 0s;
}
div.mysvg img:hover {
opacity: 1;
}
This code works for opacity, but not for fill or other svg specific attributes like stroke. I am aware I can't do that with an img tag, but I've been looking for hours and I can't find the correct way to do it with svg or object.
So basically, my questions is, how do I achieve the same result as the code which I linked, but to be able to manipulate fill, stroke etc. properties and it must be an external file, not just an inline svg code pasted in the html.
If someone is able to show me the correct way to do it, I'd be most grateful. Thanks.
EDIT:
I managed to do it by adding a css inside the .svg file itself. It must be right after the svg opening tag.
<svg ...>
<style type="text/css" media="screen">
<![CDATA[
g {
fill: yellow;
stroke: black;
stroke-width: 1;
transition: fill 1s linear 0s;
}
g:hover {
fill: blue;
}
]]>
</style>
<g>
<path ...>
</g>
</svg>
You also need to insert it as an object in the html, otherwise it won't work.
<object data="decho.svg" type="image/svg+xml">
Hopefully this helps to someone looking for an answer like mine in future. This is what helped me http://www.hongkiat.com/blog/scalable-vector-graphic-css-styling/.
This is in my opinion the greatest flaw in svg: sandboxing.
Svg files are sandboxed: in their own document, which is why a typical 'fill:' style will not apply. Likewise, the css you write in your svg will not apply to the rest of your site.
Adding css directly to an svg: Not a good solution as you will end up rewriting the css in every svg you use.
The real solution: An "icon-system". Svg font-face or svg sprites. Read more about them here.
The reason opacity works: Opacity applies to the svg object/frame itself, not the contents of the svg (which are inaccessible).
I should also note that no matter how you load those svg's, inline, by reference, in an object, as a background, you will not be able to get inside the sandbox. This is why converting them to a font or using sprites is necessary for using hover, focus, and other effects/transitions.
This is possible providing the SVG is hosted on the same domain (thanks #FabienSnauwaert) and it does not have a fill colour defined on itself, and you do not contain a parent selector within the CSS. For example:
I have the following files:
icon-sprite.svg (my external sprite of SVGs)
buttons.scss
test.html
icon-sprite.svg
I have omitted the other SVGs for clarity.
<svg xmlns="http://www.w3.org/2000/svg" style="width:0;height:0;visibility:hidden;">
<symbol viewBox="0 0 1500 828" id="icon-arrow-3pt-down">
<title>arrow-3pt-down</title>
<path d="M1500 0H0l738.9 827.7z"/>
</symbol>
</svg>
test.html
<button class="button--large">
Large button
<svg class="svg" width="20px" height="20px">
<use xlink:href="icon-sprite.svg#icon-arrow-3pt-down"></use>
</svg>
</button>
buttons.scss
.svg {
fill: red;
}
This would not work if I was to use body .svg due to shadow DOM boundaries.
See this CSS Tricks article for more info
I recently ran into this. While SVGs are not part of the DOM for some arbitrary reason, you can move them to the DOM with a bit of javascript:
<object type="image/svg+xml" data="illustration.svg"
onload="this.parentNode.replaceChild(this.contentDocument.documentElement, this);">
</object>
This will replace the <object> with an inline after it has loaded. In case javascript is disabled, it falls back to an <object> tag, and the svg will not be themed. In my case, the styling was for a javascript-controlled dark theme, so having the correct fallback means no theming issue.
Other options considered (xlink is a good one for sprites):
Use an external library to load svgs inside the DOM (the above js is simple enough IMO)
use svg filters for chroma-keying. That makes svgs more complex to edit, might use more resources to perform the filtering, and is less flexible.
Note that I am not sure of the security implications, better save this for files you control.
Unfortunately, there's no built-in feature in Web Standards that makes it possible. SVG Symbols is an option but doesn't work with files hosted on CDNs. Additionally, you need to ensure that SVG files are defined properly to make use of <use> tag.
I have created a library, svg-loader, that makes it easier to achieve this. It uses Javascript but it's only 3kb and it's loaded asynchronously, so the impact on performance is negligible. It's plug 'n play, so you don't need to do anything except including the <script> tag.
Here's a Codepen example.

HTML/CSS/SVG: SVG background image in IE7/8

I have made an svg image that I am using as a background image. I does not work in IE8 and below (as expected), and I thought I could use something use like: http://twostepmedia.co.uk/svgeezy/ or http://code.google.com/p/svgweb/. However, none of these support SVG as a background-image/background, only IMG and Object etc.
Code:
background:url('img/bck_hero.svg');
How can I get an SVG as the background in IE8/7 or have a fallback image? Is there a javascript library that could do this?
Thanks a lot,
Harley
One way is to detect support for svg with javascript and then style differently depending on that.
If you use modernizr you could do it like this in your stylesheet:
#myElm.svg { background:url('img/bck_hero.svg'); }
#myElm.no-svg { background:url('img/bck_hero.png'); }

set the quality of svg render

Usually the browser renders the svg images properly but in chrome the browser doesn't detects the css3 scale and return a poor image. This must be because css scale is a new technology... Is there any way to select the render quality?
Sorry for my english, I'm studying it!
There are a couple of workarounds for this, none as easy as setting a render quality directive, I'm afraid. The most straightforward workaround would be inserting the actual SVG instead of using it inside an img tag.
Your html would look like...
<svg>
...
</svg>
And your css would look like...
svg {
-webkit-transform: scale(2);
}
Here is a demo: http://jsfiddle.net/EgsGe/