Inline SVG breaks in Safari and Mobile Safari - css

I recently launched a site which used a bit of inline SVG.
<svg class="divider-icon" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 55.221 58.079" enable-background="new 0 0 55.221 58.079" xml:space="preserve" preserveAspectRatio="xMidYMid meet">
<path d="[...]"/>
</svg>
Everything was perfect in Chrome and Firefox, but when I tested on an iPhone or in desktop Safari, the layout was completely broken and many of the SVGs were missing. I ran the source through the W3C validator and everything was find. I work with SVG a lot, so this was very confusing...

It turns out that Safari and Mobile Safari freak out if you omit the height and width attributes I was setting the dimensions with CSS, which worked fine in other browsers. But I had to add those attributes back in to make it behave consistently:
<svg class="divider-icon" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="55.221px" height="58.079px" viewBox="0 0 55.221 58.079" enable-background="new 0 0 55.221 58.079" xml:space="preserve" preserveAspectRatio="xMidYMid meet">
<path d="[...]"/>
</svg>
Notice the width and height attributes that were missing above.
Also, it's interesting to point out that the value of preserveAspectRatio matters. I had a couple other inline SVG elements that had preserveAspectRatio="none meet" and they were unaffected by this issue.

Another scenario / fix for this is if you're scaling your SVG via CSS, to make sure that you have both max-width and max-height declared.
.whatever svg {
vertical-align: middle;
max-height: 1rem;
max-width: 1rem;
}

Related

SVG is not talking FULL 'width' of container

I am trying to make my svg full with width of the screen (container) but its not working. Could someone help me - please?
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320" preserveAspectRatio="none" class="first-svg">
<path fill="#27187F" fill-opacity="1" d="M0,192L60,170.7C120,149,240,107,360,106.7C480,107,600,149,720,170.7C840,192,960,192,1080,170.7C1200,149,1320,107,1380,85.3L1440,64L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path>
</svg>
css
.first-svg {
width: 100%;
height: 200px;
}
I am suing bootstrap for this project I am working (only for practice)
I have done the following and it seemed to work - I added the SVG inside a row.
<div class="row">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320" preserveAspectRatio="none" class="first-svg">
<path fill="#27187F" fill-opacity="1" d="M0,192L60,170.7C120,149,240,107,360,106.7C480,107,600,149,720,170.7C840,192,960,192,1080,170.7C1200,149,1320,107,1380,85.3L1440,64L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path>
</svg>
</div>

SVG invalid property value in Firefox

I am changing a background via this css:
background: url('data:image/svg+xml;utf8,<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="10px" height="11px" viewBox="0 0 10 11" enable-background="new 0 0 10 11" xml:space="preserve">
<g><g><path fill="#3477d1" d="M3.7,11c-0.3,0-0.6-0.2-0.8-0.4L0.2,6.9C-0.1,6.4,0,5.7,0.4,5.3C0.9,5,1.5,5.1,1.9,5.5L3.6,8l4.4-7.5 C8.4,0,9-0.2,9.5,0.2c0.5,0.3,0.6,1,0.3,1.5l-5.2,8.8C4.4,10.8,4.1,11,3.7,11C3.8,11,3.7,11,3.7,11z"/>
</g></g></svg>');
background-repeat: no-repeat;
background-position: center;
and it works in Chrome & Safari, however in firefox I get invalid property value and it fails to load the SVG.
I cant work out which property it is referring to.
Has anyone come across this or can point me in the right direction?
# is a reserved character in a URL as it indicates the start of a fragment identifier.
You need to URL encode the URL which will mean that the # will become %23

Change SVG Viewbox size with CSS

The Question:
Is there a way to change the size of the SVG viewbox with CSS, but preserve the aspect ratio? OR is there another way to preserve the aspect ratio of the SVG without a view box.
The Problem:
I want to responsively adjust the size of the SVG, but keep the aspect ratio. The width of the viewbox adjusts with the page, but the height doesn't adjust with the width. The problem with that is that the height of the container div is dependent on the height of the viewbox. So the container div may be really tall even if there's nothing showing in the bottom half of the viewbox.
Fiddle:
http://jsfiddle.net/hT9Jb/1/
<style>
div{
width: 100%;
height: 500px;
background-color: #00ffff;
}
svg{
width: 50%;
background-color: #ffff00;
}
</style>
<div>
<svg version="1.1" id="Layer_1" x="0px" y="0px" width="250px" height="400px" viewBox="0 0 250 400" enable-background="new 0 0 250 400" aspect-ratio="XminYmin">
<rect x="0" y="0" fill="#FF0000" width="250" height="400"/>
</svg>
</div>
(Object SVGs and img SVGs wont work for my purposes. It has to be inline. The solution doesn't have to be CSS...javascript is definitely an acceptable solution.)
You could use a transform:
transform: scale(0.75); // 75% of original size
I haven't yet found a way to change the viewBox property with CSS. However this Javascript solution works well:
var mySVG = document.getElementById('svg');
mySVG.setAttribute("viewBox", "0 0 100 100");
Also remove any references to width and height from the SVG and set them in CSS. Even though your working with an SVG, it's inline so cascading rules apply.
In order to have a flexible SVG, that allows you to change its width and height, you need to remove completely the width and height and work with viewbox instead.
And, contrary to what sansSpoon said, you do not need javascript to do this.
In your css, refer to your svg and define its max-width and max-height, for example:
.my_svg_element {
max-width: 250px;
max-height: 400px;
}
After that, your SVG will be elastic and, at the same time, will respect the max width and height you have defined before.
Did you try:
preserveAspectRatio='xMinYMin'
Check this example http://jsfiddle.net/hT9Jb/3/
For more details, see mozila documentation about svg
The width and height values specified in your SVG are the cause of your problem.
The solution is to fix your SVG file. Change:
width="250px" height="400px"
to
width="100%" height="100%"
Or with CSS:
width: 100%;
height: 100%;
What helped me was setting height and width on an img tag:
<img src="./logo.svg" height="150px" width="150px"/>
To build on the answer on #Paulo Coghi which is the best answer for me (and who saved me after a few hours of failing tests and useless googling:
Just tranform your svg from:
<svg version="1.1" id="Layer_1" x="0px" y="0px" width="250px" height="400px" viewBox="0 0 250 400" enable-background="new 0 0 250 400" aspect-ratio="XminYmin">
<rect x="0" y="0" fill="#FF0000" width="250" height="400"/>
</svg>
into:
<svg version="1.1" id="Layer_1" viewBox="0 0 250 400" >
<rect x="0" y="0" fill="#FF0000" width="250" height="400"/>
// and/or whatever you want
</svg>
then you can use in your CSS:
svg {
max-width: 100%;
max-height: 100%;
// or any other units or measurements you want
}
svg{
width: 50%;
background-color: #000;
}
<svg version="1.1" id="Layer_1" x="0px" y="0px" width="250px" height="400px" viewBox="0 0 250 400" enable-background="new 0 0 250 400" aspect-ratio="XminYmin" preserveAspectRatio="none">
<rect x="0" y="0" fill="#FF0000" width="250" height="400"/>
</svg>
Just use this and see if it works(worked for me).
<svg .... .... ... preserveAspectRatio="none">
This should work.
I found a simple javascript solution:
function setSvgSize(){
var width = document.getElementById('svg-container').offsetWidth;
var x = parseInt( $('#svg').attr('width') );
var y = parseInt( $('#svg').attr('height') );
var height = (width / x) * y;
$('#svg-container').css('height',height);
}

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.

SVG Circle Scaling

I have a simple SVG circle:
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
x="0px" y="0px" width="100px" height="100px" viewBox="0 0 100 100" overflow="visible" enable-background="new 0 0 100 100"
xml:space="preserve">
<circle fill="#6E6F6F" cx="50" cy="50" r="49"/>
</svg>
This image is being used as a background, and resized to 22px:
background: transparent url('++resource++svg/star_neg.svg') no-repeat 0 0 / 22px 22px;
When I view this in the browser, the right and bottom sides of the circle appear flat in Firefox (Chrome looks fine). If I zoom in on Firefox, the circle appears complete as expected. How can I fix this?
Finally found a simple solution. The div displaying the svg as the background should be larger than the SVG. I had the box at 22px square, the same size I was setting the SVG. To fix the issue, I displayed the box as 25px, with the background image centered instead of set in a corner.

Resources