Cannot Change SVG <use> icon size when linked to <symbol> - css

I'm trying to use an SVG symbol in my mark-up, but I can't get the CSS to increase the size of the symbol being rendered inside a element?
I have a twitter logo defined in a set of tags, and then I'm referencing this with an xlink:href inside use tags. The icon is showing, but when I add CSS to the #box1 div holding the element the symbol isn't increasing or decreasing in size and seems to only rendering at the viewBox size.
Also, the SVG element itself when I hover it with the dev tools is rendering at 300 x 150px - but there is nothing on in the code with these measurements.
I'm really confused — any help would be awesome.
#box1 {
height: 10rem;
width: 10rem;
}
<defs style="display: none;">
<svg id="twitter" viewBox="0 0 19.19 15.95">
<symbol id="twitter-symbol"><title>twitter</title>
<path id="twitter-path" d="M19.19,1.92a8.76,8.76,0,0,1-2.28.64A3.9,3.9,0,0,0,18.63.32a6.87,6.87,0,0,1-2.52,1A3.87,3.87,0,0,0,13.23,0,4,4,0,0,0,9.32,4,3.41,3.41,0,0,0,9.44,5,11,11,0,0,1,1.32.72a4.29,4.29,0,0,0-.52,2A4,4,0,0,0,2.56,6.12,3.61,3.61,0,0,1,.76,5.6v0a4,4,0,0,0,3.16,4,4.35,4.35,0,0,1-1,.16,4.9,4.9,0,0,1-.76-.08,4,4,0,0,0,3.68,2.8A7.79,7.79,0,0,1,.92,14.19a6.78,6.78,0,0,1-.92,0A10.83,10.83,0,0,0,6,16c7.24,0,11.19-6.16,11.19-11.47V4a6.83,6.83,0,0,0,2-2" fill="#000">
</path>
</symbol>
</svg>
</defs>
<div id="box1">
<svg>
<use xlink:href="#twitter-symbol"/>
</svg>
</div>

The <defs>is an svg element. It always goes inside the svg. I've made a few changes and now it works. Please run the code and take a look at what I've done.
#box1 {
height: 10rem;
width: 10rem;
}
#twitter{display:none;}
<svg id="twitter">
<defs>
<symbol id="twitter-symbol"><title>twitter</title>
<path id="twitter-path" d="M19.19,1.92a8.76,8.76,0,0,1-2.28.64A3.9,3.9,0,0,0,18.63.32a6.87,6.87,0,0,1-2.52,1A3.87,3.87,0,0,0,13.23,0,4,4,0,0,0,9.32,4,3.41,3.41,0,0,0,9.44,5,11,11,0,0,1,1.32.72a4.29,4.29,0,0,0-.52,2A4,4,0,0,0,2.56,6.12,3.61,3.61,0,0,1,.76,5.6v0a4,4,0,0,0,3.16,4,4.35,4.35,0,0,1-1,.16,4.9,4.9,0,0,1-.76-.08,4,4,0,0,0,3.68,2.8A7.79,7.79,0,0,1,.92,14.19a6.78,6.78,0,0,1-.92,0A10.83,10.83,0,0,0,6,16c7.24,0,11.19-6.16,11.19-11.47V4a6.83,6.83,0,0,0,2-2" fill="#000">
</path>
</symbol>
</defs>
</svg>
<div id="box1">
<svg viewBox="0 0 19.19 15.95" width="24">
<use xlink:href="#twitter-symbol"/>
</svg>
</div>
I hope it helps.

You're using inline SVG code within your HTML, so I believe that SVG path needs a viewbox defined within it. For example, if you add viewBox="0 0 60 55" within your HTML SVG tag, you'll notice that the size will start to adjust. So edit this part of your HTML
<svg viewBox="0 0 60 55">
<use xlink:href="#twitter-symbol"/>
</svg>
To expand on your note where you found the size listed as 300x150, this is the default standard size that applies to HTML inline SVG code (per HTML5 specs). This differs sometimes depending on the browser.
Keep in mind, there a are a few different methods you can use when handling SVGs. Check out the guide below where they give a nice run down on SVG and how to manipulate it's size. You might find an alternative way that you would prefer to use.
https://css-tricks.com/scale-svg/

Related

Viewbox placement in referencing SVG symbols and CSS dimensions

I edited my initial cry of despair into something more to the technical point, in order to turn it into a Q&A.
I'm using SVG symbols that I reference in the document with use elements. I'm styling these with CSS. I don't want to set both height and width in the CSS, I want to set only one of them with the other one scaling accordingly.
I do set a viewBox attribute on the symbol. But the graphic does not scale correctly.
<!DOCTYPE html>
<html>
<head>
<title>SVG Symbols</title>
<style>
body { margin: 20px; }
.svg-large { width: 500px; fill: yellow;}
</style>
</head>
<body>
<svg style="display:none;">
<symbol id="scary-smiley" viewBox="0 0 20 20">
<circle cx="10" cy="10" r="9.5" stroke-width="1"
stroke="black" />
<circle cx="6" cy="7" r="1.5" fill="black"/>
<circle cx="14" cy="7" r="1.5" fill="black"/>
<image xlink:href="https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Teeth_by_David_Shankbone.jpg/320px-Teeth_by_David_Shankbone.jpg"
width="10" height="5.2" x="5" y="11"/>
</symbol>
</svg>
<svg class="svg-large">
<use xlink:href="#scary-smiley"/>
</svg>
</body>
</html>
The code below has been tested in current Firefox, Chrome and a Webkit-based browser named Midori.
For some reason, defining the viewBox on the symbol element does not have the full desired effect in Firefox and Chrome. It does have some effect, though, as it makes the element scaleable. So, if you want set both width and height in CSS, you can do that.
If the viewBox element is specified only on the symbol and you set only one of width or height, then in Firefox and Chrome the other dimension is set according the default object size in HTML 5 whis is 300x150 px. So, in the example in the question, you get a 500x150 px element and the graphic is scaled to fit that rectangle.
If you want to define only one width or height with the other one scaling accordingly, then defining viewBox on the referencing SVG element works:
<!DOCTYPE html>
<html>
<head>
<title>SVG Symbols</title>
<style>
body { margin: 20px; }
.svg-large { width: 500px; fill: yellow;}
</style>
</head>
<body xmlns:xlink="http://www.w3.org/1999/xlink">
<svg style="display:none;">
<symbol id="scary-smiley">
<circle cx="10" cy="10" r="9.5" stroke-width="1"
stroke="black" />
<circle cx="6" cy="7" r="1.5" fill="black"/>
<circle cx="14" cy="7" r="1.5" fill="black"/>
<image xlink:href="https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Teeth_by_David_Shankbone.jpg/320px-Teeth_by_David_Shankbone.jpg"
width="10" height="5.2" x="5" y="11"/>
</symbol>
</svg>
<svg class="svg-large" viewBox="0 0 20 20">
<use xlink:href="#scary-smiley"/>
</svg>
</body>
</html>
Firefox' and Chrome's behaviour is standard compliant, according to the SVG 2 specification, according to which the <svg><use .../></svg> clause establishes a new SVG viewport.

How can I change SVG fill color inside an object without putting any css code inside the svg file

How can I change the SVG fill color on hover inside an object tag without putting any CSS code inside the svg file? Here's my code:
<div class="icon-holder">
<object data="http://useaible.com/wp-content/themes/storefront/assets/images/icons/bulb-round.svg"></object>
</div>
I know that CSS won't work if it's not inside the SVG-file. Is there another way on implementing a hover effect without using inline SVG nor using CSS inside the SVG-file?
You can use SVG sprites. Define your svg after your body like that :
<svg style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-facebook" viewBox="0 0 16 32">
<title>facebook</title>
<path class="path1" d="M4.973 30.593v-13.872h-4.973v-4.984h4.974v-4.433c0-4.595 2.775-7.303 6.874-7.303 1.964 0 3.66 0.211 4.152 0.276v5.053l-3.393-0.001c-2.229 0-2.646 1.106-2.646 2.66v3.749h5.711l-0.807 4.984h-4.904v13.872h-4.988z"></path>
</symbol>
</defs>
</svg>
and call it in your code :
<svg class="icon-facebook"><use xlink:href="#icon-facebook"></use></svg>
That way you can aply CSS on it.

How can I affect a non-child element on hover?

So I'm trying to make it so that when you hover a list item, it changes the color of the corresponding svg shape. Since these are elements in separate divs is it possible to do this with just css?
Here's a Codepen of what I have so far:
http://codepen.io/rewerbj/pen/LVLRaK
Would I then have to give each svg section a different class name?
I've tried:
.region-list li:hover + .map-shape {
fill: #213A46;
}
That didn't work so I'm not sure if I'm going to have to use jQuery and if so what the most dynamic way to do this would be.
Any suggestions are welcome. Thank you!
You can not do this since the (+) sibling operator only works in adjacent div.
so to achieve this effect either you have to change your HTML in such a way so that shape comes just after the menu or you have to use Jquery
If you want to do this with CSS only you would have to restructure your titles to be adjacent to your SVG map pieces using the + operator (you can read more about that here). Here is an example of your code if you decide to go this route.
HTML
<div class="region-map-wrap">
<div class="region-map">
<div class="title1"><span class="num">1</span><span class="city">one</span></div>
<svg class="item1" 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"
width="97.907px" height="102.533px" viewBox="0 0 97.907 102.533" enable-background="new 0 0 97.907 102.533"
xml:space="preserve">
<g>
<polygon class="map-shape" fill="#009A8B" stroke="#000000" stroke-miterlimit="10" points="4.559,101.959 0.513,25.768 33.772,0.623 97.33,47.07
84.834,90.274 "/>
<circle fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" cx="43.626" cy="55.002" r="24.27"/>
<text transform="matrix(1 0 0 1 35.839 65.252)" fill="#FFFFFF" font-family="'OpenSans'" font-size="28.0337">1</text>
</g>
</svg>
</div>
</div>
CSS
.title1 {
font-size: 18px;
font-family: verdana;
}
.title1:hover + .item1 .map-shape {
fill: #213A46;
}
Also added a JS.Fiddle if you want to play with it. Notice that the title is now just above your SVG item.
EDIT:
Messed around with JQuery using this Fiddle and you can hover SVG elements by setting the Attribute Fill element to a hexadecimal value.
$('.region-list .item').hover(function(){
$(this).addClass('active');
$('.region-map .map-shape').attr("fill", "#ff0000");
}, function(){
$(this).removeClass('active');
$('.region-map .map-shape').attr("fill", "#009A8B");
});

Style part of svg when using it via use

Is it possible style an svg icon embedded using the svg-use syntax only within a certain item?
I can easily style the icon in general, but I would like to style a part of an svg icon when the icon is used within the nav-item.
This is what I tried without any success.
// css
.nav-item .part1{
opacity: 0.5;
}
When using the svg like this:
<svg id="svg_sprite" style="display: none;">
<defs>
<g id="icon">
<polygon points="476.5,379.778 401.167,..."></polygon>
<polygon class="page1" points="221,379.768 85.334,..."></polygon>
</g>
</defs>
</svg>
<li class="nav-item">
<svg viewBox="0 0 512 512" class="icon">
<use xlink:href="#icon"></use>
</svg>
</li>
The answer is no. You cannot style an element based on whether it has been referenced by a <use> or not. The SVG spec specifically says this. The reason is that the content referenced by the <use> is only a "conceptual clone" and is not actually part of the DOM.
http://www.w3.org/TR/SVG11/struct.html#UseElement

Inline SVG element with fluid height

I want to include an inline SVG for a project. I can dump the SVG generated from inkscape into a HTML document and it displays. This is a responsive site, so I want the element to resize fluidly. I keep running into an issue with the height of the SVG element being the height of the document at page load.
<div id="svg">
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" preserveAspectRatio="xMinYMin meet" viewBox="0 0 500 500" id="svg4107">
<defs id="defs4109"></defs>
<g transform="translate(0,-552.3622)" id="layer1">
<path d="m 0,552.3622 500,0 c -505.952711,505.95 -225.92979,225.93 -500,500 z" id="rect3260" style="fill:#ffffff;fill-opacity:1;stroke:none"></path>
</g>
</svg>
</div>
The css is like this:
body {
padding: 0;
margin: 0;
}
#svg {
width: 50%;
background-color: red;
}
With images I'm used to setting a width as a percentage and height:auto, but that doesn't seem to work with inline SVG.
This a simplified example, the production situation is a much more complicated SVG - but this illustrates the issue well. This needs to be a HTML/CSS solution (no Javascript).
Here is a fiddle of the issue
Note: As pointed out in the comments this seems to be a blink/webkit issue - firefox works fine.

Resources