SVG apply same transform-origin to all children of a group/symbol - css

I can't get reusable items or all children of a group to conform to a specified transform-origin. The goal is to be able to reuse the same shape over and over with the same template of style. However, considering transform-origin the styling, CSS or otherwise, does not cascade. It will only apply at time of <use>.
For example:
svg {
width: 125px; height: 125px;
background: rgba(0, 0, 0, 0.5);
}
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
<defs>
<ellipse id="svg-ellipse-def" cx="500" cy="500" rx="140" ry="455" transform-origin="center" style="transform-origin: center"/>
</defs>
<symbol id="svg-ellipse" >
<ellipse cx="500" cy="500" rx="140" ry="455" transform-origin="center" style="transform-origin: center"/>
</symbol>
<g fill="none" stroke="red" stroke-width="50">
<use xlink:href="#svg-ellipse"/>
<use xlink:href="#svg-ellipse" transform="rotate(45)"/>
<use xlink:href="#svg-ellipse" transform="rotate(90)"/>
<use xlink:href="#svg-ellipse-def" transform="rotate(-45)"/>
</g>
</svg>
Essentially, the transform origin doesn't apply regardless if I use class= attribute or transform-origin= property or even inline style. I've also tried wrapping it in a <defs> container.
Desired outcome:
<use xlink:href="#svg-ellipse" transform="rotate(45)"/>
<use xlink:href="#svg-ellipse" transform="rotate(90)"/>
<use xlink:href="#svg-ellipse" transform="rotate(-45)"/>
But right now it looks like this:
<use xlink:href="#svg-ellipse" transform="rotate(45)" style="transform-origin:center"/>
<use xlink:href="#svg-ellipse" transform="rotate(90)" style="transform-origin:center"/>
<use xlink:href="#svg-ellipse" transform="rotate(-45)" style="transform-origin:center"/>
svg {
width: 125px; height: 125px;
background: rgba(0,0,0,0.5);
}
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
<symbol id="svg-ellipse" >
<ellipse cx="500" cy="500" rx="140" ry="455"/>
</symbol>
<g fill="none" stroke="red" stroke-width="50">
<use xlink:href="#svg-ellipse"/>
<use xlink:href="#svg-ellipse" transform="rotate(45)" transform-origin="center"/>
<use xlink:href="#svg-ellipse" transform="rotate(90)" transform-origin="center"/>
<use xlink:href="#svg-ellipse" transform="rotate(-45)" transform-origin="center"/>
</g>
</svg>
According to the documentation:
If the ‘use’ element references a ‘symbol’ element:
In the generated content, the ‘use’ will be replaced by ‘g’, where all attributes from the ‘use’ element except for ‘x’, ‘y’, ‘width’, ‘height’ and ‘xlink:href’ are transferred to the generated ‘g’ element. An additional transformation translate(x,y) is appended to the end (i.e., right-side) of the ‘transform’ attribute on the generated ‘g’, where x and y represent the values of the ‘x’ and ‘y’ attributes on the ‘use’ element. The referenced ‘symbol’ and its contents are deep-cloned into the generated tree, with the exception that the ‘symbol’ is replaced by an ‘svg’.
Looking at the dev console, this is confirmed, and the style is applied inline but not honored:
Even if the <use> element has an inline styling of transform-origin, because the symbol now is converted to it's own SVG as a child of the <use> element, and it has it's own inline styling, shouldn't that take higher priority over it's parent's inline?

You can target the <use> element itself, but none of its content. The content can, in principle, inherit CSS properties. But the barrier you'll always run into is: neither the CSS transform nor the transform-origin property are inheritable.
If you rotate the <use> element, you rotate it around the tranform origin of the <use> element, while the contents of the shadow DOM stay in place relative to its root.
If you set a transform-origin for the <symbol> or <ellipse>, it will only be applied if you transform that itself, and the transformation will be cloned into each of its reuses.
The best solution I see is giving all use elements that reference the same symbol the same transform-origin. For the attribute selector to work, you'll need to leave off the xlink namespace. That is deprecated anyway, but you'll have to consider browser compatibility.
But then, the same is true for transform-origin support in SVG. That, by the way is the reason for
setting transform-box: fill-box. After there were some differences in implementation between Firefox and Chrome, it is now accepted that this
property is needed for SVG elements to transform them in relation to their bounding box. I've changed your example a bit to demonstrate.
svg {
width: 125px; height: 125px;
background: rgba(0, 0, 0, 0.5);
}
use[href="#symbol1"] {
transform-origin: center;
transform-box: fill-box;
}
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1500 1500">
<symbol id="symbol1" >
<ellipse cx="500" cy="500" rx="140" ry="455" />
</symbol>
<g fill="none" stroke="red" stroke-width="50">
<use href="#symbol1" transform="translate(200, 400)" />
<use href="#symbol1" transform="translate(200, 400) rotate(45)"/>
<use href="#symbol1" transform="translate(200, 400) rotate(90)"/>
<use href="#symbol1" transform="translate(200, 400) rotate(-45)"/>
</g>
</svg>

Related

SVG radius or position with CSS variables

Is it possible to use CSS Variables in SVG to manipulate values like radius or position in the "attribute styles" of an element?
For Example, in the below code, I have added a CSS color variable - --dark-text-clr and a radius variable --radius. When I use the color CSS variable in fill it renders fine - 1st circle, but using the radius variable doesn't render the element - 2nd circle.
:root{
--dark-text-clr: blue;
--radius: 12;
}
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="100px" viewBox="0 0 300 100">
<circle cx="9" cy="9" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=9 ></circle>
<circle cx="36" cy="20" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r="var(--radius)" ></circle>
</svg>
Yes, but CSS must have units for non-zero values.
:root{
--dark-text-clr: blue;
--radius: 12px;
}
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="100px" viewBox="0 0 300 100">
<circle cx="9" cy="9" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=9 ></circle>
<circle cx="36" cy="20" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r="var(--radius)" ></circle>
</svg>
According to the MDN Docs "Starting with SVG2, r is a Geometry Property meaning this attribute can also be used as a CSS property for circles."
There are three ways to set the radius value
as attribute
<circle ... r=10>
via class and stylesheet
circle {
r: 10px;
}
inline in 'style' attribute
<circle... style="r: 10px;" ></circle>
The last way has the greates presedence. Take a look at this example where all circle elements have r set as attribute, which is overridden by the stylesheet (2nd circle), which is overridden again by the inline style attribute (3rd circle)
(These three ways don't have to be used together, but are only combined to demontrate which one has a higher presedence and overwrites the already set values)
:root {
--dark-text-clr: purple;
--radius: 20px;
}
.circle {
r: 10px;
}
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="300px" viewBox="0 0 300 300">
<circle cx="10" cy="10" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=5></circle>
<circle cx="30" cy="30" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=5 class="circle"></circle>
<circle cx="60" cy="60" fill="var(--dark-text-clr)" mask="url(#moon-mask)" r=5 class="circle" style="r: var(--radius);" ></circle>
</svg>
Setting r with the variable on the attribute seems to be working in firefox, but not in chrome/edge
<circle ... r="var(--radius);" ></circle>
so better set it on the style attribute
<circle ... style="r: var(--radius);" ></circle>

How to control `transform-box` for `<use>` elements?

Background
I’m loving the expanded CSS support in SVG2. It’s great not having to rewrite attributes over and over. So I’ve been converting some code in a project from SVG attributes to CSS. Most of this has worked just fine.
When it comes to transforms, things can seem tricky if you are comfy with how CSS transforms work in HTML. (This is especially true for rotate() transformations, which is the focus of this question.) That’s because SVG doesn’t have the “automatic flow” that HTML does.
In other words, when you have a bunch of HTML elements, one after another, they will automatically lay themselves out according to the box model.
There is no such “automatic” or “default” layout in SVG. As a result, SVG transforms default to being calculated from the origin. (That’s 0,0 in user coordinates).
The Almost-Perfect Solution
For most elements, there’s a simple solution: the awesome CSS property transform-box. In most cases, using the following CSS will allow you to transform SVG elements in pretty much the same way as HTML elements:
/* whatever elements you want to transform */
rect, polygon {
transform-box: fill-box;
transform-origin: center center; /* or `top left`, `center right`, etc. */
}
.rotate90 {
transform: rotate(90deg);
}
Now, you can just do something like...
<rect class="rotate90" x="123" y="789" width="50" height="50" />
And it will rotate around the transform-origin specified in the CSS. Since the above example used a transform-origin of center center, it rotates in place.
That matches the behavior of HTML elements using transform: rotate(…). And—especially if there’s a lot of rotations like this in an SVG image—it is way, way better than the equivalent SVG markup.
Why is CSS better than the SVG markup equivalent?
Because SVG’s rotate() function has a slightly different syntax that does not have an equivalent to the transform-box: fill-box CSS used above, unless you specify an X and Y coordinate for every rotation.
That means you have to put in the rotation point every time, like so:
<rect x="123" y="789" width="50" height="50"
transform="rotate(90 123 789)"
></rect>
<!--
In this example, the rotation pivots around the X and Y coordinates of the `rect` element.
If you wanted to rotate around the center, you would have to calculate:
x + width/2
y + width/2
And use those values in the `rotate()` function instead.
-->
The Problem
The problem I’ve run into is that the CSS solution does not work with <use /> elements.
It’s pretty clear why: the <use /> element clones the referenced element into a new location. So, as far as the CSS is concerned, it is transforming the <use /> element, and not the cloned (Shadow-DOM) content.
When it comes to other challenges involving applying CSS to <use />—such as setting up different color schemes—there are solutions (like this one from SVG superhero Sara Soueidan).
But when it comes to getting around the issue of coordinates, I haven’t figured out a way around this.
Example Code
EDIT: To be more explicit about what I’m going for, here is some sample code.
.transform-tl,
.transform-tc,
.transform-tr,
.transform-cl,
.transform-cc,
.transform-cr,
.transform-bl,
.transform-bc,
.transform-br {
transform-box: fill-box;
}
.transform-tl { transform-origin: top left; }
.transform-tc { transform-origin: top center; }
/*
…and so on, for the other combinations of `transform-origin` keyword values…
*/
.rotate90.cw {
transform: rotate(90deg)
}
.rotate90.ccw {
transform: rotate(-90deg)
}
<!--
Using the CSS classes in the following manner works as intended for most SVG elements as intended.
But with the `<use />` element, the rotation does not pivot around the top left corner, as expected... :(
-->
<use
class="transform-tl rotate90 cw"
x ="0"
y ="1052"
href ="#block-A12-2"
></use>
(Thanks to #PaulLeBeau for the nudge to include this bit of code.)
Does anyone have a solution?
(Even a workaround solution—as long as it involves less repetition than specifying the SVG transform attribute on every <use />—would be welcome!)
Assuming the same conditions as #Sphinxxx postulated...
Then you can also just wrap your <use> element in a group (<g>) element and apply the rotate class to that.
/* whatever elements you want to transform */
rect, polygon, use, g {
transform-box: fill-box;
transform-origin: center center; /* or `top left`, `center right`, etc. */
}
.rotate45 {
transform: rotate(45deg);
}
<svg width="300" height="200">
<defs>
<rect id="rr" x="80" y="60" width="50" height="50" />
</defs>
<use href="#rr" x="100" y="0" fill="tomato" />
<g class="rotate45">
<use href="#rr" x="100" y="0" fill="lime" />
</g>
</svg>
What's going on? Why does this work?
The reason has to do with how <use> elements are dereferenced and what happens to transforms when that happens. If you read the section about <use> elements in the SVG spec, it says:
In the generated content, the ‘use’ will be replaced by ‘g’, where all attributes from the ‘use’ element except for ‘x’, ‘y’, ‘width’, ‘height’ and ‘xlink:href’ are transferred to the generated ‘g’ element. An additional transformation translate(x,y) is appended to the end (i.e., right-side) of the ‘transform’ attribute on the generated ‘g’, where x and y represent the values of the ‘x’ and ‘y’ attributes on the ‘use’ element.
So, the following SVG (which I presume will be something like you were trying):
<use href="#rr" x="100" y="0" fill="lime" class="rotate45" />
will be dereferenced into the equivalent of:
<g fill="blue" transform="rotate(45) translate(100,0)">
<rect x="80" y="60" width="50" height="50" />
</g>
Since you can think of transforms as being applied from right to left, the translate(100,0) will be applied before the rotation, meaning that the rotation will be moving something that is offset 100 pixels away from where you want it. That's why the transform-box: fill-box is not working for <use> elements.
rect, polygon, use, g {
transform-box: fill-box;
transform-origin: center center; /* or `top left`, `center right`, etc. */
}
.rotate45 {
transform: rotate(45deg);
}
<svg width="300" height="200">
<defs>
<rect id="rr" x="80" y="60" width="50" height="50" />
</defs>
<use href="#rr" x="100" y="0" fill="tomato" />
<use href="#rr" x="100" y="0" fill="blue" stroke="blue" class="rotate45" />
<g fill="lime" transform="rotate(45) translate(100,0)">
<rect x="80" y="60" width="50" height="50" />
</g>
</svg>
However with my solution, the <g> + <use> set...
<g class="rotate45">
<use href="#rr" x="100" y="0" fill="lime" />
</g>
will be dereferenced into the equivalent of:
<g class="rotate45">
<g fill="lime" transform="translate(100,0)">
<rect x="80" y="60" width="50" height="50" />
</g>
</g>
rect, polygon, use, g {
transform-box: fill-box;
transform-origin: center center; /* or `top left`, `center right`, etc. */
}
.rotate45 {
transform: rotate(45deg);
}
<svg width="300" height="200">
<defs>
<rect id="rr" x="80" y="60" width="50" height="50" />
</defs>
<use href="#rr" x="100" y="0" fill="tomato" />
<g class="rotate45">
<use href="#rr" x="100" y="0" fill="blue" stroke="blue"/>
</g>
<g class="rotate45">
<g fill="lime" transform="translate(100,0)">
<rect x="80" y="60" width="50" height="50" />
</g>
</g>
</svg>
In this version, each of the two transform operations is applied to different elements, so the transform-box and transform-origin are applied separately. And the transform origin has no effect on translations.
So what that means is that the transform-box calculation for the rotation (ie on the <g>) will be applied to the already-translated object. So it will behave as you want.
In the days before transform-box, these two examples would have given the same result.
So you want to put an element somewhere with <use x="..." y="...", and then rotate it in place?
The simplest solution I have found does include the transform attribute, but you don't need to specify the rotation point. See the following example, where the green rectangle does what you want.
In CSS, we include use elements in the transform-box rule. Then we position and rotate each element with the transform attribute (replacing x, y and CSS rotation):
/* whatever elements you want to transform */
rect, polygon, use {
transform-box: fill-box;
transform-origin: center center; /* or `top left`, `center right`, etc. */
}
.rotate45 {
transform: rotate(45deg);
}
<svg width="300" height="200">
<rect id="rr" x="80" y="60" width="50" height="50" />
<use href="#rr" x="100" y="0" class="rotate45" fill="tomato" />
<use href="#rr" transform="translate(100 0) rotate(45)" fill="lime" />
</svg>

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.

Animated growing arrow link

Hi, I was wondering how one would go about animating an svg arrow like above (on hover).
I have tried playing around with CSS transforms, but they also scale the arrow-head which is no good. I assume the correct way to do this is using SVGs animations, but I don't know where to start.
For example I would the following arrow (line only) to grow and arrow head to move accordingly.
<svg width="600px" height="100px">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#f00" />
</marker>
</defs>
<line x1="50" y1="50" x2="100" y2="50" stroke="#000" stroke-width="5" marker-end="url(#arrow)" />
</svg>
Any help is very much appreciated!
You can create growing arrow by using "respoinsive" SVG like this.
svg{
width: 20px;
height: 20px;
transition:width 2s ease;
overflow: visible;
}
svg:hover{
width: 100px;
}
<svg>
<defs>
<marker id="m" markerWidth="4" markerHeight="8"
refX="0" refY="1" viewBox="0 0 1 2">
<polygon points="0,0 1,1 0,2" fill="black"/>
</marker>
</defs>
<line x1="0" y1="50%" x2="100%" y2="50%"
stroke-width="2" marker-end="url(#m)" stroke="black"/>
</svg>
There are some points to implement.
svg has no viewBox (so it is "responsive" SVG).
Line of arrow is defined by relative position of (root) svg size.
Arrow head is defined by marker element.
Growing animation is defined by CSS transition which animate width of svg. So, arrow grows with svg size.
In order to animate the individual SVG elements like HTML elements, you'll need to embed the SVG directly into the page like this:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="612px" height="502.174px" viewBox="0 65.326 612 502.174" enable-background="new 0 65.326 612 502.174"
xml:space="preserve" class="logo">
<ellipse class="ground" cx="283.5" cy="487.5" rx="259" ry="80"/>
<path class="kiwi" d="M210.333,65.331C104.367,66.105-12.349,150.637,1.056,276.449c4.303,40.393,18.533,63.704,52.171,79.03
c36.307,16.544,57.022,54.556,50.406,112.954c-9.935,4.88-17.405,11.031-19.132,20.015c7.531-0.17,14.943-0.312,22.59,4.341
c20.333,12.375,31.296,27.363,42.979,51.72c1.714,3.572,8.192,2.849,8.312-3.078c0.17-8.467-1.856-17.454-5.226-26.933
c-2.955-8.313,3.059-7.985,6.917-6.106c6.399,3.115,16.334,9.43,30.39,13.098c5.392,1.407,5.995-3.877,5.224-6.991
c-1.864-7.522-11.009-10.862-24.519-19.229c-4.82-2.984-0.927-9.736,5.168-8.351l20.234,2.415c3.359,0.763,4.555-6.114,0.882-7.875
c-14.198-6.804-28.897-10.098-53.864-7.799c-11.617-29.265-29.811-61.617-15.674-81.681c12.639-17.938,31.216-20.74,39.147,43.489
c-5.002,3.107-11.215,5.031-11.332,13.024c7.201-2.845,11.207-1.399,14.791,0c17.912,6.998,35.462,21.826,52.982,37.309
c3.739,3.303,8.413-1.718,6.991-6.034c-2.138-6.494-8.053-10.659-14.791-20.016c-3.239-4.495,5.03-7.045,10.886-6.876
c13.849,0.396,22.886,8.268,35.177,11.218c4.483,1.076,9.741-1.964,6.917-6.917c-3.472-6.085-13.015-9.124-19.18-13.413
c-4.357-3.029-3.025-7.132,2.697-6.602c3.905,0.361,8.478,2.271,13.908,1.767c9.946-0.925,7.717-7.169-0.883-9.566
c-19.036-5.304-39.891-6.311-61.665-5.225c-43.837-8.358-31.554-84.887,0-90.363c29.571-5.132,62.966-13.339,99.928-32.156
c32.668-5.429,64.835-12.446,92.939-33.85c48.106-14.469,111.903,16.113,204.241,149.695c3.926,5.681,15.819,9.94,9.524-6.351
c-15.893-41.125-68.176-93.328-92.13-132.085c-24.581-39.774-14.34-61.243-39.957-91.247
c-21.326-24.978-47.502-25.803-77.339-17.365c-23.461,6.634-39.234-7.117-52.98-31.273C318.42,87.525,265.838,64.927,210.333,65.331
z M445.731,203.01c6.12,0,11.112,4.919,11.112,11.038c0,6.119-4.994,11.111-11.112,11.111s-11.038-4.994-11.038-11.111
C434.693,207.929,439.613,203.01,445.731,203.01z"/>
<filter id="pictureFilter" >
<feGaussianBlur stdDeviation="15" />
</filter>
</svg>
After doing this, you can use CSS animations on any of the individual SVG elements, just like HTML elements. For example, you could do the following:
svg ellipse { animate: grow 3s infinite; }
Without having the exact SVG code for your arrow, I can't give you more specific direction than that, but can point you in the direction of this article: https://css-tricks.com/using-svg/

IE 11 :after background size not working

I added a background-image inside the pseudo :after
::after {
content: '';
display: block;
position: absolute;
right: -2.5rem;
bottom: -1.5rem;
height: 9.5rem;
width: 9.5rem;
background-image: url('../img/icons/icon_logo.svg');
background-repeat: no-repeat;
// background-size: 100% auto;
background-size: cover;
}
But the image is way bigger than the actual size of the box.
Any idea how to solve this?
(Working fine in webkit browsers)
!!!Additional Information:
I tried other svg and it works great.
Works:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
<path fill="#FF6C00" d="M0 0h64v64H0z"/>
<path fill="#FFF" d="M33 0C22 0 13 9 ..."/>
</svg>
Does not work:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
<path fill="#FFF" d="M0 0h64v64H0z"/>
<defs>
<path id="a" d="M0 0h64v64H0z"/>
</defs>
<clipPath id="b">
<use xlink:href="#a" overflow="visible"/>
</clipPath>
<path fill="#277052" d="M43.7 51.8s-...."/>
<defs>
<path id="c" d="M0 0h64v64H0z"/>
</defs>
<clipPath id="d">
<use xlink:href="#c" overflow="visible"/>
</clipPath>
<path fill="#EE7203" d="M40.7 28.7c0 4.8-3..." clip-path="url(#d)"/>
<path fill="#1D1D1B" d="M43 10.9c.2.1.4 0..." clip-path="url(#d)"/>
</svg>
Read this link
Adobe Illustrator give me four options to declaring style sheet properties when saving graphics as an SVG file
Presentation Attributes
Style Attributes
Style Attributes (Entity Reference)
Style Elements
No problem using the first three ways to styling properties, but embedding style sheets into SVG content inside a element cause the problem!
I had similar issues rendering CSS in IE.
My solution:
Make sure you have a <!DOCTYPE> declaration before your html
Add the meta tag <meta http-equiv="X-UA-Compatible" content="IE=edge" > (this makes sure that your code always renders the cutting edge or most updated version of internet explorer; else, it can render from older versions and things get really messy.)
I hope that helps.
Try adding in display:block to the css.

Resources