Svg image does not show in Firefox - html

Inside a simple SVG element I have an image.
Chrome: Version 28. - works perfect
Firefox: 22.0 - no image is drawn
Opera: 12.16 - image is show 4 times larger than normal
Code:
<svg width="500px" height="500px" viewBox="0 0 70 70">
<image x="0" y="0" width="10" height="10"
id="knight" xlink:href="/images/knight.svg" />
</svg>

Your SVG is not being scaled to fit your 10x10 image rectangle because it has no viewBox. SVG renderers need to know the dimensions of the SVG content in order to know how to scale it. That is what the viewBox attribute is for.
Try adding the following to the root <svg> element in knight.svg.
viewBox="0 0 45 45"
Also, you need to define your namespaces for svg and xlink. Although perhaps you have just removed those for clarity(?).

Your knight is 45 x 45 pixels in size. The top left corner (10 x 10) pixels is blank.
You are asking for the image to be displayed for that top left corner in the <image> markup so Firefox correctly shows nothing because there's nothing there.
If you want to see the knight, make the <image> width and height 45 to match the underlying knight.svg dimensions.
Neither Chrome nor Opera seem to display the image correctly
An ‘image’ element establishes a new viewport for the referenced file as described in Establishing a new viewport. The bounds for the new viewport are defined by attributes ‘x’, ‘y’, ‘width’ and ‘height’

Related

How do I scale an SVG to adjust with screen size? [duplicate]

I want to have an inline svg element's contents scale when size is non-native. Of course I could have it as a separate file and scale it like that.
index.html: <img src="foo.svg" style="width: 100%;" />
foo.svg: <svg width="123" height="456"></svg>
However, I want to add additional styles to the SVG thru CSS, so linking an external one is not an option. How do I make an inline SVG scale?
To specify the coordinates within the SVG image independently of the scaled size of the image, use the viewBox attribute on the SVG element to define what the bounding box of the image is in the coordinate system of the image, and use the width and height attributes to define what the width or height are with respect to the containing page.
For instance, if you have the following:
<svg>
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>
It will render as a 10px by 20px triangle:
Now, if you set only the width and height, that will change the size of the SVG element, but not scale the triangle:
<svg width=100 height=50>
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>
If you set the view box, that causes it to transform the image such that the given box (in the coordinate system of the image) is scaled up to fit within the given width and height (in the coordinate system of the page). For instance, to scale up the triangle to be 100px by 50px:
<svg width=100 height=50 viewBox="0 0 20 10">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>
If you want to scale it up to the width of the HTML viewport:
<svg width="100%" viewBox="0 0 20 10">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>
Note that by default, the aspect ratio is preserved. So if you specify that the element should have a width of 100%, but a height of 50px, it will actually only scale up to the height of 50px (unless you have a very narrow window):
<svg width="100%" height="50px" viewBox="0 0 20 10">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>
If you actually want it to stretch horizontally, disable aspect ratio preservation with preserveAspectRatio=none:
<svg width="100%" height="50px" viewBox="0 0 20 10" preserveAspectRatio="none">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>
(note that while in my examples I use syntax that works for HTML embedding, to include the examples as an image in StackOverflow I am instead embedding within another SVG, so I need to use valid XML syntax)
After like 48 hours of research, I ended up doing this to get proportional scaling:
NOTE: This sample is written with React. If you aren't using that, change the camel case stuff back to hyphens (ie: change backgroundColor to background-color and change the style Object back to a String).
<div
style={{
backgroundColor: 'lightpink',
resize: 'horizontal',
overflow: 'hidden',
width: '1000px',
height: 'auto',
}}
>
<svg
width="100%"
viewBox="113 128 972 600"
preserveAspectRatio="xMidYMid meet"
>
<g> ... </g>
</svg>
</div>
Here's what is happening in the above sample code:
VIEWBOX
MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox
min-x, min-y, width and height
ie: viewbox="0 0 1000 1000"
Viewbox is an important attribute because it basically tells the SVG what size to draw and where. If you used CSS to make the SVG 1000x1000 px but your viewbox was 2000x2000, you would see the top-left quarter of your SVG.
The first two numbers, min-x and min-y, determine if the SVG should be offset inside the viewbox.
My SVG needs to shift up/down or left/right
Examine this: viewbox="50 50 450 450"
The first two numbers will shift your SVG left 50px and up 50px, and the second two numbers are the viewbox size: 450x450 px. If your SVG is 500x500 but it has some extra padding on it, you can manipulate those numbers to move it around inside the "viewbox".
Your goal at this point is to change one of those numbers and see what happens.
You can also completely omit the viewbox, but then your milage will vary depending on every other setting you have at the time. In my experience, you will encounter issues with preserving aspect ratio because the viewbox helps define the aspect ratio.
PRESERVE ASPECT RATIO
MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio
Based on my research, there are lots of different aspect ratio settings, but the default one is called xMidYMid meet. I put it on mine to explicitly remind myself. xMidYMid meet makes it scale proportionately based on the midpoint X and Y. This means it stays centered in the viewbox.
WIDTH
MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/width
Look at my example code above. Notice how I set only width, no height. I set it to 100% so it fills the container it is in. This is what is probably contributing the most to answering this Stack Overflow question.
You can change it to whatever pixel value you want, but I'd recommend using 100% like I did to blow it up to max size and then control it with CSS via the parent container. I recommend this because you will get "proper" control. You can use media queries and you can control the size without crazy JavaScript.
SCALING WITH CSS
Look at my example code above again. Notice how I have these properties:
resize: 'horizontal', // you can safely omit this
overflow: 'hidden', // if you use resize, use this to fix weird scrollbar appearance
width: '1000px',
height: 'auto',
This is additional, but it shows you how to allow the user to resize the SVG while maintaining the proper aspect ratio. Because the SVG maintains its own aspect ratio, you only need to make width resizable on the parent container, and it will resize as desired.
We leave height alone and/or set it to auto, and we control the resizing with width. I picked width because it is often more meaningful due to responsive designs.
Here is an image of these settings being used:
If you read every solution in this question and are still confused or don't quite see what you need, check out this link here. I found it very helpful:
https://css-tricks.com/scale-svg/
It's a massive article, but it breaks down pretty much every possible way to manipulate an SVG, with or without CSS. I recommend reading it while casually drinking a coffee or your choice of select liquids.
You'll want to do a transform as such:
with JavaScript:
document.getElementById(yourtarget).setAttribute("transform", "scale(2.0)");
With CSS:
#yourtarget {
transform:scale(2.0);
-webkit-transform:scale(2.0);
}
Wrap your SVG Page in a Group tag as such and target it to manipulate the whole page:
<svg>
<g id="yourtarget">
your svg page
</g>
</svg>
Note: Scale 1.0 is 100%
Messing around & found this CSS seems to contain the SVG in Chrome browser up to the point where the container is larger than the image:
div.inserted-svg-logo svg { max-width:100%; }
Also seems to be working in FF + IE 11.
Here's an easy way:
Type 1: Most SVGs have a viewbox, like so:
<svg viewBox="0 0 24 30" ...>
And you can easily control their size in css:
svg {
height: 20px;
}
Type 2: If the svg has width and height, but doesn't have a viewport, like so:
<svg width="810" height="540">
Then you can just manually add a viewbox that's exactly the same as its width and hegith, like so:
<svg width="810" height="540" viewBox="0 0 810 540">
Then you can do the same as type 1.
Another simple way is
transform: scale(1.5);
changing the SVG file was not a fair solution for me so instead, I used relative CSS units.
vh, vw, % are very handy. I used a CSS like height: 2.4vh; to set a dynamic size to my SVG images.
If you want to scale SVG without preserveAspectRatio attribute.
This way SVG will always stretch to fill both width and height, and to do so, it will resize just width or height, if necessary, was looking for this for days, so thought to share it here in case someone else is looking for this
You have to remove width and height from <svg> and add viewBox attribute and add preserveAspectRatio="none"
example
<?xml version="1.0" encoding="utf-8"?>
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 5.8208332 15.9"
preserveAspectRatio="none">
<polygon points="480.4,200 0,200 0,0 480.4,0 599.9,100 " fill="#E1E1E1"/>
</svg>
Adjusting the currentScale attribute works in IE ( I tested with IE 11), but not in Chrome.

Is viewbox in SVG important?

What is the role of View-box in SVG and what if we don't provide it?
Is it important?
viewBox is the difference between your SVG being responsive and not.
With a viewBox if you rescale your canvas, the contents will rescale too, without it the contents will stay the same size and you'll either be able to see more or less of it kind of like putting a picture frame over a picture.
The viewBox attribute defines the position and dimension, in user
space, of an SVG viewport. The value of the viewBox attribute is a list of four numbers:
min-x, min-y, width, and height. The numbers separated by whitespace
and/or a comma, which specifies a rectangle in user space which is
mapped to the bounds of the viewport established for the associated
SVG element
This is referenced from MDN docs. Basically, you are setting the coordinates and width and height of your SVG. The syntax is - viewBox = "min-x min-y width height". The purpose of viewBox is to select that part of the your SVG plane, that should actually be rendered onto the page.
Without the viewBox tag and without any width or height specified, the svg won't scale. Here's an example -
<!--This one is without a viewbox which wont scale-->
<svg>
<path d="M 15,5 25,27.5 5,27.5 z"/>
</svg>
<!--This one is with a viewbox which will scale. Check by opening in full page-->
<svg viewBox="0 0 200 200">
<path d="M 15,5 25,27.5 5,27.5 z"/>
</svg>

How can I avoid overlapping stroks cancelling each other? (Defect?)

I have the following SVG in an HTML page.
<svg preserveAspectRatio='none' xmlns='http://www.w3.org/2000/svg' viewBox="0 0 1 1">
<circle class='spath' cx="0.5" cy="0.5" r="0.02" stroke="green" stroke-width="0.08" fill="none"/>
</svg>
The stroke-width is more than enough to cover the entire width of the circle. Instead of a solid circle though I get the following rendering:
Wherever the stroke overlaps itself from the other side it gets cancelled -- it draws nothing on the overlapping parts.
Is there some CSS/SVG setting to avoid this, or is it a Firefox rendering defect? (On Linux)
For reference, here is a stroke-width="0.05", which should not be filling less of the circle (like 0.08, it should completely fill it).
And this is 0.4, the size required to fill the circle. Since it lacks any overlap it appears to draw correctly.
Note: I'm unable to workaround the problem by calculating the exact size required. This is just a reduced example with a simple path. My full SVG has many curves and different points of overlap.

SVG CSS | SVG only works in chrome

Having issues with an SVG I have made.
It works great in chrome and does exactly what i want and expect it too but I cannot get it working in any other browser (tried IE and Firefox so far).
My SVG is an image with a clip path cutting it out into the shape I want and this works on different resolutions spanning the full page width. Below is how it looks in chrome including an image of when the page width expands
The html for the SVG looks as follows
<svg id="mobile-svg" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 875.67 321.8" preserveAspectRatio="none">
<defs>
<style>.cls-1{fill:#60b6e1;}</style>
</defs>
<clipPath id="myClip">
<path d="M0,0S1,7.68,12.63,18.54,364.25,297.4,364.25,297.4s30.77,27.3,84.06.38,379.59-192,379.59-192S873.34,87.5,875.67,0H0Z" transform="translate(0)"></path>
</clipPath>
<image class="cls-image" xlink:href="http://localhost:63342/Carfinance247Rebrand/Content/img/carDrivingImage.png" clip-path="url(#myClip)"/>
</svg>
The CSS for the SVG (.SCSS)
#mobile-svg {
margin-bottom: -3px;
background-color: #5fb6e0;
.cls-image {
width: 100%;
height: 115%;
}
}
All works in chrome as expected but see image below for Firefox, the same thing also happens in IE (version 9 - 11)
I have tried changing position types and display types, also setting set width and ehights but cant get it to appear in other browsers.
I ahve an SVG that uses clip paths at a different point in the page and this one works fine, hence the confusion for this one. See image below of my working SVG
inb4 I am relatively new to SVG's
In SVG 1.1 an <image> element must have height and width attributes i.e. you can't set the height and width via CSS.
In SVG 2 it is proposed that image elements have width and height that are CSS properties.
Only Chrome has so far implemented this part of the SVG 2 specification.

properly align svg polygon

So, i've been trying to make a portfolio page and i want to use custom shapes. So instead of use divs, i'm using a svg polygon shape to have the background img. Note, this is the first time i deal with svg and i'm trying to fix it the whole day.
So basically, the problem is, the border on the left-bottom and on the top-right is cutting out the edge of my shpe. I tried to reduce the the width/height of the polygon but it's not working properly. It stays to small or cut even more making it a swuare shape..
This is my html code and also a working jsfiddle: http://jsfiddle.net/1rmd2otz/1/
<div class="sv-img">
<svg class="svg" viewBox="0 0 910 500" >
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="900" height="490">
<image xlink:href="img/service/website.jpg" x="0" y="0" width="890" height="480" />
</pattern>
</defs>
<polygon points="96.729,27.124 0,490.109 867.032,420.878 900,0" fill="url(#img1)"/>
</svg>
</div>
So, can anyone help me?
Okay I see a couple of things wrong. Let's start with the first and work through it.
For a start, your polygon is 900x490, but you are specifying a pattern with dimensions of 890x480. So that's part of the reason why you are getting "trimmed" corners - your pattern isn't extending the full width and height of the polygon.
If we fix that, we get almost there. I've added a red line to show the polygon outline more clearly.
Here's a demo.
It is still not quite right. There are still little gaps at the top and bottom. The reason for this is because the aspect ratio of your polygon/pattern (900/490 ~= 1.84) is not the same as the aspect ratio of your image (570/300 = 1.9). What the renderer is doing is scaling the 500x370 image up to fit inside the dimensions you specify for your <image>, whilst keeping the same aspect ratio. That results in an image that is 900 x 473.7 (473.7 = 900/1.9), centred vertically in your 900x490 pattern. That's leaving roughly 6 pixels at the top and bottom.
There are a few ways to fix that. Obviously one would be to change either the image or the polygon so their aspect ratios match exactly.
Another way to fix this is to change the way the image gets scaled. By default, the image gets scaled up to fit the width and height you specify, but doesn't go outside those dimensions. This means that sometimes a gap will be left - like we are seeing. You can change it to a different scaling mode which tells it to scale to fit the maximum dimension leaving no gaps. You do that by setting preserveAspectRatio="xMidYMid slice" on the image.
<image xlink:href="[...snip...]"
x="0" y="0" width="900" height="490" preserveAspectRatio="xMidYMid slice"/>
Here's a demo of that.
You can see that the polygon is completely filled now.
You can read more about preserveAspectRatio here.
It looks like your issue is in the polygon points. Change ...
<polygon points="96.729,27.124 0,490.109 867.032,420.878 900,0" fill="url(#img1)"/>
To ...
<polygon points="96.729,27.124 10,470.109 867.032,420.878 890,10" fill="url(#img1)"/>
jsFiddle: http://jsfiddle.net/rfornal/1rmd2otz/3/
This may not be EXACTLY what you want, but should get you moving in the right direction. You MIGHT be able to do this on the other side and change the SVG viewBox values (widen them).