Reuse SVG images while maintaining css control - html

I have some silhouette type images and they need to be able to change color, sometimes just to display in different locations, sometimes for hover effects.
This is easy enough to do with the SVG directly embedded into the HTML. Copy-paste and CSS to your heart's desire.
But then I have to copy-paste or programatically insert everywhere I want it. Some of these are used dozens of times. It just seems poor practice to re-transmit the same SVG markup repeatedly.
Is there a best-of-both-worlds solution, where I can CSS the paths and also somehow reuse the SVG on the front-end?

There is a tag in svg that let's you reuse "symbols". I think that is as close as you'll get.
You create a symbol by wrapping your paths etc in a symbol-element. Give it an id (so you can re-use it later):
<svg style="display: none;">
<symbol id="ic">
<paths and polygons and other fun stuff>
</symbol>
</svg>
Now you can reuse this symbol with <use> and xlink:href pointing to the symbol you made. And you can add classes freely to change things up:
<svg viewBox="0 0 100 125" xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="#ic" class="ic-blue" x="0" y="0" />
</svg>
Examples and code shamelessly plucked from https://tympanus.net/codrops Go read their content and click their ads! If there ever was a site deserving an exception in your ad-blocker, this is it.
https://tympanus.net/codrops/2015/07/16/styling-svg-use-content-css/
body {
padding: 2em;
}
svg {
width: 100px;
height: 125px;
border: 1px solid #ddd;
}
use.ic-1 {
fill: skyblue;
}
use.ic-2 {
fill: #FDC646;
}
use.ic-3 {
fill: #FF2D49;
}
svg path {
fill: inherit;
}
<svg style="display: none;">
<symbol id="ic">
<path fill="#000000" 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>
<svg viewBox="0 0 100 125" xmlns:xlink="http://www.w3.org/1999/xlink">
<use class="ic-1" xlink:href="#ic" x="0" y="0" />
</svg>
<svg viewBox="0 0 100 125" xmlns:xlink="http://www.w3.org/1999/xlink">
<use class="ic-2" xlink:href="#ic" x="0" y="0" />
</svg>
<svg viewBox="0 0 100 125" xmlns:xlink="http://www.w3.org/1999/xlink">
<use class="ic-3" xlink:href="#ic" x="0" y="0" />
</svg>

Related

Why doesn't an SVG with a <use> tag scale like a regular SVG?

I have an SVG icon, I'm setting a fixed height for it (50px, say), but I want its width to be auto, that is, whatever it needs to be depending on the icon. (Pretty common and normal scenario, right?).
Now, the problem that I've been beating my head against the wall for, is that instead of embedding the SVG inline in the HTML, I'm intending to define it with the <symbol> tag and then reference it using the <use href="... tag, and doing so apparently requires me to set a fixed width as well as a fixed height or otherwise it will always default to about 150px, instead of just defaulting to the width of icon; this is not the case when you embed the SVG directly, you can see all of this in action in the following two snippets:
Directly-embedded SVG: (Works as expected, width is consistent with the width of the icon)
.icon {
height: 50px;
width: auto;
/* Aesthetics: */
background-color: gray;
border-radius: 5px;
}
<svg class="icon" viewBox="0 0 22.832 27.398">
<g transform="translate(-42.667)"> <g transform="translate(42.667)"> <path class="a" d="M62.074,9.133V7.991a7.991,7.991,0,1,0-15.982,0V9.133a3.429,3.429,0,0,0-3.425,3.425V23.973A3.429,3.429,0,0,0,46.092,27.4H62.074A3.429,3.429,0,0,0,65.5,23.973V12.557A3.429,3.429,0,0,0,62.074,9.133Zm-13.7-1.142a5.708,5.708,0,0,1,11.416,0V9.133H48.375ZM63.216,23.973a1.143,1.143,0,0,1-1.142,1.142H46.092a1.143,1.143,0,0,1-1.142-1.142V12.557a1.143,1.143,0,0,1,1.142-1.142H62.074a1.143,1.143,0,0,1,1.142,1.142Z" transform="translate(-42.667)"></path> </g> <g transform="translate(50.658 13.128)"> <path class="a" d="M195.425,245.333a3.416,3.416,0,0,0-1.142,6.639v1.922a1.142,1.142,0,1,0,2.283,0v-1.922a3.416,3.416,0,0,0-1.142-6.639Zm0,4.566a1.142,1.142,0,1,1,1.142-1.142A1.143,1.143,0,0,1,195.425,249.9Z" transform="translate(-192 -245.333)"></path> </g> </g>
</svg>
But using the <use> tag: (Width is coming from nowhere!)
.icon {
height: 50px;
width: auto;
/* Aesthetics: */
background-color: gray;
border-radius: 5px;
}
<svg style="display: none;">
<symbol id="lock" viewBox="0 0 22.832 27.398">
<g transform="translate(-42.667)"> <g transform="translate(42.667)"> <path class="a" d="M62.074,9.133V7.991a7.991,7.991,0,1,0-15.982,0V9.133a3.429,3.429,0,0,0-3.425,3.425V23.973A3.429,3.429,0,0,0,46.092,27.4H62.074A3.429,3.429,0,0,0,65.5,23.973V12.557A3.429,3.429,0,0,0,62.074,9.133Zm-13.7-1.142a5.708,5.708,0,0,1,11.416,0V9.133H48.375ZM63.216,23.973a1.143,1.143,0,0,1-1.142,1.142H46.092a1.143,1.143,0,0,1-1.142-1.142V12.557a1.143,1.143,0,0,1,1.142-1.142H62.074a1.143,1.143,0,0,1,1.142,1.142Z" transform="translate(-42.667)" /> </g> <g transform="translate(50.658 13.128)"> <path class="a" d="M195.425,245.333a3.416,3.416,0,0,0-1.142,6.639v1.922a1.142,1.142,0,1,0,2.283,0v-1.922a3.416,3.416,0,0,0-1.142-6.639Zm0,4.566a1.142,1.142,0,1,1,1.142-1.142A1.143,1.143,0,0,1,195.425,249.9Z" transform="translate(-192 -245.333)" /> </g> </g>
</symbol>
</svg>
<svg class="icon">
<use href="#lock"></use>
</svg>
I've already checked out this question, as well as this one, and I've realized that by adding the "viewBox" of the icon to the referencing SVG, the problem would be solved, like this:
.icon {
height: 50px;
width: auto;
/* Aesthetics: */
background-color: gray;
border-radius: 5px;
}
<svg style="display: none;">
<symbol id="lock" viewBox="0 0 22.832 27.398">
<g transform="translate(-42.667)"> <g transform="translate(42.667)"> <path class="a" d="M62.074,9.133V7.991a7.991,7.991,0,1,0-15.982,0V9.133a3.429,3.429,0,0,0-3.425,3.425V23.973A3.429,3.429,0,0,0,46.092,27.4H62.074A3.429,3.429,0,0,0,65.5,23.973V12.557A3.429,3.429,0,0,0,62.074,9.133Zm-13.7-1.142a5.708,5.708,0,0,1,11.416,0V9.133H48.375ZM63.216,23.973a1.143,1.143,0,0,1-1.142,1.142H46.092a1.143,1.143,0,0,1-1.142-1.142V12.557a1.143,1.143,0,0,1,1.142-1.142H62.074a1.143,1.143,0,0,1,1.142,1.142Z" transform="translate(-42.667)" /> </g> <g transform="translate(50.658 13.128)"> <path class="a" d="M195.425,245.333a3.416,3.416,0,0,0-1.142,6.639v1.922a1.142,1.142,0,1,0,2.283,0v-1.922a3.416,3.416,0,0,0-1.142-6.639Zm0,4.566a1.142,1.142,0,1,1,1.142-1.142A1.143,1.143,0,0,1,195.425,249.9Z" transform="translate(-192 -245.333)" /> </g> </g>
</symbol>
</svg>
<svg class="icon" viewBox="0 0 22.832 27.398"> <!-- Copy-pasted the viewbox here -->
<use href="#lock"></use>
</svg>
But obviously this is very inconvenient, repetitive, error-prone, and indeed ugly to write. So, I'd appreciate any workarounds. Isn't there a way to set the viewBox attribute to "auto" or something which means "whatever the inner SVG is", so as to avoid writing (or copy-pasting, rather) the viewBox each time you want to reference an icon?
To be honest, I think everyone would intuitively kind of expect this to work like regular embedded SVGs since the viewBox is already set once on the symbol that is being referenced.
I'd highly recommend:
Make all your icons have a consistent viewBox. For example, "0 0 24 24" is a common one that many icon libraries use. That way you don't have to find and copy the correct viewBox where you need it. It's always "0 0 24 24".
Add a class to the referencing <svg> that you can use for setting the icon width.
<svg class="icon lock" viewBox="0 0 24 24">
<use href="#lock"></use>
</svg>
Then in your CSS:
.icon {
// as above
}
.icon.lock {
width: 45px;
height: 50px;
}
.icon.something-else {
width: 35px;
height: 50px;
}
As long as your icon is horizontally centred in its viewBox, everything will work.
Default size (square) icons need no extra CSS. You only need to add a CSS rule for the non-square ones.
If you're not opposed to using some JavaScript, the following should work. Load it once, no matter how many icons you have on your page.
document.querySelectorAll(".icon").forEach(node => {
const href = node.querySelector("use").href.baseVal;
const icon = document.querySelector(href);
const vb = icon.viewBox.baseVal;
node.setAttribute("viewBox", `${vb.x} ${vb.y} ${vb.width} ${vb.height}`);
});
.icon {
height: 50px;
width: auto;
/* Aesthetics: */
background-color: gray;
border-radius: 5px;
}
<svg style="display: none;">
<symbol id="lock" viewBox="0 0 22.832 27.398">
<g transform="translate(-42.667)">
<g transform="translate(42.667)">
<path
class="a"
d="M62.074,9.133V7.991a7.991,7.991,0,1,0-15.982,0V9.133
a3.429,3.429,0,0,0-3.425,3.425V23.973A3.429,3.429,0,0,0,46.092,27.4
H62.074A3.429,3.429,0,0,0,65.5,23.973V12.557
A3.429,3.429,0,0,0,62.074,9.133Z
m-13.7-1.142a5.708,5.708,0,0,1,11.416,0V9.133H48.375Z
M63.216,23.973a1.143,1.143,0,0,1-1.142,1.142H46.092
a1.143,1.143,0,0,1-1.142-1.142V12.557a1.143,1.143,0,0,1,1.142-1.142
H62.074a1.143,1.143,0,0,1,1.142,1.142Z"
transform="translate(-42.667)">
</path>
</g>
<g transform="translate(50.658 13.128)">
<path
class="a"
d="M195.425,245.333a3.416,3.416,0,0,0-1.142,6.639v1.922
a1.142,1.142,0,1,0,2.283,0v-1.922a3.416,3.416,0,0,0-1.142-6.639Z
m0,4.566a1.142,1.142,0,1,1,1.142-1.142
A1.143,1.143,0,0,1,195.425,249.9Z"
transform="translate(-192 -245.333)">
</path>
</g>
</g>
</symbol>
</svg>
<svg class="icon">
<use href="#lock"></use>
</svg>
If you want to add icons dynamically - after page load, the following would also be an improvement over adding a manual viewBox:
function iconLoaded(event) {
const node = event.target;
const href = node.querySelector("use").href.baseVal;
const icon = document.querySelector(href);
const vb = icon.viewBox.baseVal;
node.setAttribute("viewBox", `${vb.x} ${vb.y} ${vb.width} ${vb.height}`);
}
.icon {
height: 50px;
width: auto;
/* Aesthetics: */
background-color: gray;
border-radius: 5px;
}
<svg style="display: none;">
<symbol id="lock" viewBox="0 0 22.832 27.398">
<g transform="translate(-42.667)">
<g transform="translate(42.667)">
<path
class="a"
d="M62.074,9.133V7.991a7.991,7.991,0,1,0-15.982,0V9.133
a3.429,3.429,0,0,0-3.425,3.425V23.973A3.429,3.429,0,0,0,46.092,27.4
H62.074A3.429,3.429,0,0,0,65.5,23.973V12.557
A3.429,3.429,0,0,0,62.074,9.133Z
m-13.7-1.142a5.708,5.708,0,0,1,11.416,0V9.133H48.375Z
M63.216,23.973a1.143,1.143,0,0,1-1.142,1.142H46.092
a1.143,1.143,0,0,1-1.142-1.142V12.557a1.143,1.143,0,0,1,1.142-1.142
H62.074a1.143,1.143,0,0,1,1.142,1.142Z"
transform="translate(-42.667)">
</path>
</g>
<g transform="translate(50.658 13.128)">
<path
class="a"
d="M195.425,245.333a3.416,3.416,0,0,0-1.142,6.639v1.922
a1.142,1.142,0,1,0,2.283,0v-1.922a3.416,3.416,0,0,0-1.142-6.639Z
m0,4.566a1.142,1.142,0,1,1,1.142-1.142
A1.143,1.143,0,0,1,195.425,249.9Z"
transform="translate(-192 -245.333)">
</path>
</g>
</g>
</symbol>
</svg>
<svg class="icon" onload="iconLoaded(event)">
<use href="#lock"></use>
</svg>

Set inline SVG fill color by CSS related to outside classname

I want to load a SVG several times on my html page, and change the color of a path to different values related to a class outside the svg:
.red svg path {
fill: #ff0000;
}
.green svg path {
fill: #00ff00;
}
But is does not work. All the paths have the color of the first svg on the page.
Why is it like that, and what are the possibilities to have the same inline SVG with different fill colors on one page?
I build a jsfiddle: https://jsfiddle.net/1p0svg9u/
The problem is that you use the ID "Pattern" twice. Each ID may only be used once, or the browser will only interpret the first occurrence. The second SVG refers to the first pattern and is therefore red. Just rename the second ID.
.red {
margin-bottom: 50px;
}
.red svg path {
fill: #ff0000;
}
.green svg path {
fill: #00ff00;
}
<div class='red'>
<p>
Red triangles
</p>
<svg viewBox="0 0 10000 20" width="10000" height="20" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<defs>
<pattern id="Pattern" x="0" y="0" width=".006" height="20">
<path d="M15 10L0 0L30 0L60 0L45 10L30 20L15 10Z"></path>
</pattern>
</defs>
<rect fill="url(#Pattern)" width="10000" height="20"/>
</svg>
</div>
<div class='green'>
<p>
Green triangles
</p>
<svg viewBox="0 0 10000 20" width="10000" height="20" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<defs>
<pattern id="Patterntwo" x="0" y="0" width=".006" height="20">
<path d="M15 10L0 0L30 0L60 0L45 10L30 20L15 10Z"></path>
</pattern>
</defs>
<rect fill="url(#Patterntwo)" width="10000" height="20"/>
</svg>
</div>

How to reference different SVGs inside the same SVG file in CSS background?

I am creating a website and a very important requirement of this website is to have a minimal number of files. One place where I can reduce the number of files are the SVG files of the project. Currently this project is using 10+ SVG files and I hope to combine them all into one SVG sprite sheet. Since these SVG files were being used as background images in CSS:
.class-name {
background-image: url(/path/to/file.svg)
}
I now have an svg file, where each one of the previous SVG files is a symbol, so the svg file looks like this:
<svg>
<symbol id="id1">....</svg>
<symbol id="id2">....</svg>
<symbol id="id3">....</svg>
...
</svg>
I wish to use these symbols in my CSS as follows:
.class-name {
background-image: url(/path/to/combined-file.svg#id1)
}
How can I use the SVG symbols in my background image.
I have already tried the following:
.class-name {
background-image: url(/path/to/combined-file.svg#id1)
}
and also
.class-name {
background-image: url("data:image/svg+xml;base64,<svg><use xlink:href="path/to/combined-svg#id1/></svg>"");
}
I have also tried converting all the <symbol> tags to <g> tags but then all the images start to overlap each other and therefore it becomes pointless.
I am hoping for a solution where all my SVG are in one file and i can reference them individually in my CSS background image.
This is an example where I'm using svg sprites as background:
div{width:300px;height:300px; border:1px solid;
background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/cat.svg#redcat);
background-size:200px;
background-repeat: no-repeat;
background-position: center;
}
<div></div>
You can also use the #blackcat
The combined file looks like this:
(Please observe the style element where this rule svg > svg:not(:target) {display: none;} is hiding all the nested svg elements unless they are the target)
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px" viewBox="0 0 225 225">
<style type="text/css">
<![CDATA[
/* this is hiding all the nested svg elements unless they are the target*/
svg > svg:not(:target) {
display: none;
}
]]>
</style>
<desc>
<g id="cat">
<path id="body" fill-rule="evenodd" clip-rule="evenodd" d="M121.506,108.953.....108.953z"/>
<path id="head" fill-rule="evenodd" clip-rule="evenodd" d="M129.747,18.651......81.453z"/>
</g>
</desc>
<svg version="1.1" id="blackcat" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 225 225">
<use xlink:href ="#cat" fill="black" />
</svg>
<svg version="1.1" id="redcat" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 225 225">
<use xlink:href ="#cat" fill="red" />
</svg>
</svg>
I hope this is what you need.
You will find this explained in detail in this book: Using SVG with CSS3 and HTML5: Vector Graphics for Web Design

How can I bundle many SVG images inside just one?

It's not bad if I load an HTML page
img, svg {
background-color: #eee;
margin: 20px;
}
<div>
<img src="circle.svg"/>
<img src="square.svg"/>
</div>
with just a pair of SVG images
circle.svg
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 400 300" width="400" height="300">
<circle cx="200" cy="150" r="100"
stroke="red" fill="blue" stroke-width="10" />
</svg>
square.svg
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 400 300" width="400" height="300">
<rect x="100" y="50" width="200" height="200"
stroke="green" fill="gray" stroke-width="10" />
</svg>
but with over a hundred SVG images, the server gets excessively hit by requests.
One solution is to serve the static files from a dedicated server, but this only dodges the problem. The number of requests remains high.
How can I bundle many SVG images inside just one?
You could use a SVG sprite generator to create one big file with all images aligned in it.
SVG sprite generator will also generate a CSS file in which each individual SVG will be represented with a specific class.
In you HTML you just have to call each image by its class name.
A basic sprite.css could be :
.svg {
background-image: url(sprite.svg) no-repeat;
}
.circle {
background-position: top left;
height:300px;
width: 400px;
}
.square{
background-position: top right;
height:200px;
width: 200px;
}
And then in your html file you could just call:
<div>
<div class="circle"></div>
<div class="square"></div>
</div>
It sounds like you need an SVG sprite. I use this trick all the time. It's great. Just make your svg blocks symbol elements and nest them inside an svg like this:
<svg id="svg-sprite" xmlns="http://www.w3.org/2000/svg">
<symbol id="svg-circle" viewBox="0 0 400 300" width="400" height="300">
<circle cx="200" cy="150" r="100" stroke="red" fill="blue" stroke-width="10" />
</symbol>
<symbol id="svg-square" viewBox="0 0 400 300" width="400" height="300">
<rect x="100" y="50" width="200" height="200" stroke="green" fill="gray" stroke-width="10" />
</symbol>
</svg>
Note that you don't want the xlmns attribute on the individual symbol elements, just the root svg. And the root svg doesn't need a viewBox attribute, since that is encoded in the child symbol elements.
Then you call the symbols elsewhere in the HTML like this via the <use> tag:
<svg>
<use xlink:href="#svg-circle"></use>
</svg>
Lastly, you need to hide the sprite in CSS:
#svg-sprite {
display: none;
}
Here's a Fiddle to demonstrate. Good luck!
The following is a combination of gael's and maqam7's answers, with a bug fix and some details.
First, we combine the two SVGs into one. (We write our own script, use an editor's macros, use one of the web sites that do it, or do it by hand.)
sprite.svg
<svg id="mysprite" xmlns="http://www.w3.org/2000/svg">
<symbol id="circle"
viewBox="0 0 400 300"
width="400" height="300">
<circle cx="200" cy="150" r="100"
stroke="red" fill="blue" stroke-width="10" />
</symbol>
<symbol id="square"
viewBox="0 0 400 300"
width="400" height="300">
<rect x="100" y="50" width="200" height="200"
stroke="green" fill="gray" stroke-width="10" />
</symbol>
</svg>
When we want a circle or a square, we use the xlink:href attribute (deprecated but continue to use it), which will invoke a sub-sprite.
<div class="container">
<svg>
<use xlink:href="sprite.svg#circle"></use>
</svg>
<svg>
<use xlink:href="sprite.svg#square"></use>
</svg>
</div>
There is no need to include the sprite in the body
<img src="sprite.svg"/>
as the sprite is referenced within each svg element.
Hence there is no need to hide the global sprite.
#svg-sprite {
display: none;
}
Only the sub-parts appear.
One caveat: Chrome loads an img and svg directly, but will refuse to load use/xlink:href unless you run a local server.
Remaining issue(s)
I'm not sure this is optimal. It may be that two requests continue to be sent. It's just that the cache will catch the second as identical. No harm is done. Still, loading once via a hidden svg may be a better approach, if someone can fill in the details.

Request part of SVG in <img> (or <object>)

Could I load only part of a SVG (that could be identified by an #id tag) in an <img> or <object> tag ?
Reason (if I need one) is I don't want to have two SVG files if I'm only using part of a already in use one.
If I can't by using these tags, could I by using CSS or other means ?
Please take a look at this svg file in view-source. Inside the root svg there are 2 other svg elements. Those 2 svg elements have an id each and the style is saying that the nestedsvg elements are visible only if :target.
svg > svg:not(:target) {
display: none;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px" viewBox="0 0 225 225">
<style type="text/css">
<![CDATA[
svg > svg:not(:target) {
display: none;
}
]]>
</style>
<desc>
<g id="cat">
<path id="body" fill-rule="evenodd" clip-rule="evenodd" d="M121.506,..."/>
<path id="head" fill-rule="evenodd" clip-rule="evenodd" d="M129.747,..."/>
</g>
</desc>
<svg version="1.1" id="blackcat" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 225 225">
<use xlink:href ="#cat" fill="black" />
</svg>
<svg version="1.1" id="redcat" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 225 225">
<use xlink:href ="#cat" fill="red" />
</svg>
</svg>
Here is how to use one of those svg elements as an image or as an object:
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/cat.svg#redcat" width="200" />
<object width="200" data="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/cat.svg#blackcat"></object>
What you want to achieve is easiest done with another inline SVG instead of a <img> or <object> tag:
<svg style="width:200px;height:200px" viewBox="35 50 150 150">
<use xlink:href="myFile.svg#head" />
</svg>
Two things you need to get right are
the viewBox: to get just the part of your SVG that you want, you have to identify where the path is and what bounding box it has. The <use> element takes care that only the element you select is visible, but it does not identify where inside that image the element is.
the overall size your selected element is shown at. SVG has no notion of a "natural size, you always have to give a width and height. The viewBox will then be fitted inside that area.