SVG element appears to have arbitrary height - html

I've been really trying to learn some SVG. But browsers seem to get in a right old muddle rendering it.
Take the following HTML:
<html>
<head></head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink">
<rect height="100" width="100" style="stroke:#006600; fill: #00cc00"/>
</svg>
<p>Hello? Hellooooooooooooo?</p>
</body>
</html>
View this is any modern browser and you'll see an arbitrary amount of whitespace between the rectangle and the following HTML paragraph. (IE9 doesn't display anything but noone will be surprised about that.)
Firefox (Firebug) doesn't give the heights of either the svg or the rect elements. It just wimps out and says 'auto'.
Opera says the svg has a height of 150px and says 'auto' for the rect.
Chrome mans up and gives heights for both. 102px for the rect (obviously including the stroke) and 428px for the svg.
My expectation is that the svg element would be a 'thin' container (i.e. add nothing to the dimensions of its contents) and therefore have a height of 102px.
Anyone know what the correct behaviour should be and how I might go about fixing this?

You've not explicitly defined what the width or height of the SVG is, or where the rectangle is placed, or even what part of the SVG is of interest. It's hardly surprising browsers are dealing with things differently.
Try defining a width and height:
<svg xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="102px" height="102px">
<rect height="100" width="100" style="stroke:#006600; fill: #00cc00"/>
</svg>
Alternatively, define a viewBox:
<svg xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" viewBox="0 0 102 102">
<rect height="100" width="100" style="stroke:#006600; fill: #00cc00"/>
</svg>
Or both:
<svg xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" viewBox="-50 -50 52 52" width="102px" height="102px">
<rect height="100" width="100" style="stroke:#006600; fill: #00cc00"/>
</svg>
Here are some examples in action.

Related

SVG icons are very large when inlining the SVG to the HTML document

I have essentially this:
<body>
<svg style="display:none">
<symbol id="mysymb1" viewBox="0 0 200 500">
<g>
<path ...></path>
</g>
</symbol>
<symbol id="mysymb2" viewBox="0 0 200 500">
<g>
<path...></path>
</g>
</symbol>
</svg>
<div>
<svg viewBox="0 0 10 25">
<use xlink:href="#mysymb1"></use>
</svg>
</div>
</body>
My symbols I want to be large during development so I can get in there with some detail, but then when I use them I want them to be like small icons.
The problem is, however, that the icon is showing up extremely large, like over 1000px width and height, causing scrolling and everything. This is pretty much literally the code I have. There's no nested svg elements anywhere, and the paths don't extend beyond the 200/500 bounds.
Not sure what to do to make it work so that the icon is small as defined. TBH I always have this problem with SVG and I'm not sure why it happens.
You need to set the size via CSS. Otherwise the SVG is as large as possible. The viewBox is not the relevant part for resizing an SVG in HTML/CSS.
Example code:
svg {
height: 50px;
width: 20px;
}

How do you get HTML to adjust to SVG scaling

When I scale an SVG using the scale transform, the surrounding html does not respect this scale and fails to adjust its size.
I have the following SVG:
<div>
<svg height="300" width="300" viewbox="0 0 300 300" transform="scale(1.55)"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xml="http://www.w3.org/XML/1998/namespace" version="1.1">
<circle r="150px" cx="150px" cy="150px" fill="orange"/>
</svg>
</div>
<div>
<svg height="300" width="300" viewbox="0 0 300 300" transform="scale(1.55)"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xml="http://www.w3.org/XML/1998/namespace" version="1.1">
<circle r="150px" cx="150px" cy="150px" fill="green"/>
</svg>
</div>
For some reason the surrounding html doesn't adjust for the scaled up Svg.
All my testing so far has been on chrome and using primarily Svg declared in millimeter units.
When tested, the above example with the scale transform, the two circles overlap.
Without the transform they do not.
I want them NOT to overlap when scaled.
How can I get the Html to correctly adjust with the scaling of Svg?
Thanks in advance.
You have set fixed height and width and fixed pixels for your svg.
You have to change the properties of your svg and the actual circle path to correct it like in my example.
the transform property is something you don't need here in my opinion!
Try to change that and your HTML will surround like you want.
<div>
<svg height="100" width="100" viewbox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xml="http://www.w3.org/XML/1998/namespace" version="1.1">
<circle r="100px" cx="100px" cy="100px" fill="orange"/>
</svg>
</div>
<div>
<svg height="100" width="100" viewbox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xml="http://www.w3.org/XML/1998/namespace" version="1.1">
<circle r="100px" cx="100px" cy="100px" fill="green"/>
</svg>
</div>
That should do the job!
I think the problem is that, in SVG 1.1, I believe it wasn't properly defined how a transform attribute behaved when placed on a root <svg> element.
In SVG2 it has been. The behavior is defined in the CSS Transforms specification.
Chrome seems to have implemented that, but Firefox hasn't yet done so for SVGs. The behaviour in Chrome seems correct. transform on <svg> elements behaves the same as an HTML element (see example below).
<div>
<svg height="300" width="300" viewbox="0 0 300 300" transform="scale(1.55)"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xml="http://www.w3.org/XML/1998/namespace" version="1.1">
<circle r="150px" cx="150px" cy="150px" fill="orange"/>
</svg>
</div>
<div>
<div style="width:300px; height:300px; background-color:green; border-radius:50%; transform:scale(1.55)">
</div>
</div>

SVG Circle with pattern image only renders on chrome, why not firefox and edge?

I am trying to render an image inside a circle with svg. This works on chrome, but not other browsers, what am I doing wrong?
I have included several possible ways of specifying the link to the image, href= is what works with chrome. I can't get any of these to work elsewhere. If I change the fill to #000 it fills with black - so the problem is in the pattern.
<svg width="488.20001220703125" height="469.183349609375" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="circleimage" x="135.99766906738282" y="126.2336688232422" patternUnits="userSpaceOnUse" height="206.440673828125"
width="206.440673828125">
<image x="0" y="0" href="https://res.cloudinary.com/hrltiizbo/image/upload/c_scale,h_207/v1456513725/capitol_crowd_wrong_way_andwo1.jpg"
xmlns:xlink="https://res.cloudinary.com/hrltiizbo/image/upload/c_scale,h_207/v1456513725/capitol_crowd_wrong_way_andwo1.jpg"
xlink="https://res.cloudinary.com/hrltiizbo/image/upload/c_scale,h_207/v1456513725/capitol_crowd_wrong_way_andwo1.jpg"></image>
</pattern>
</defs>
<circle cx="239.21800598144532" cy="229.4540057373047" r="103.2203369140625" fill="url(#circleimage)"></circle>
</svg>
You need to specify the height and width of your image.

Embedded svg isn't scaled correctly

I'm trying to embed an svg inside an svg (the real application is to be able to embed an image in a d3 chart). Here's a simplified version:
<svg viewBox="0 0 200 200" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="0" cy="0" r="80" style="fill:blue" />
<image x="10" y="20" width="120" height="150" xlink:href="https://webkit.org/blog-files/circle.svg" />
</svg>
The embedded image scales correctly if it's a raster image (png/jpg), but not an svg. Here's a fiddle of it not working - the big red rectangle should actually be this circle.
https://jsfiddle.net/rg4kyuc7/1/
How do I get the svg to scale to the specified width and height?
Edit - working on Chrome but not Firefox?! Any ideas why?
The behaviour of <image> changed a little between SVG 1.1 and the upcoming SVG 2.
It looks like Chrome is following the SVG 2 behaviour. Chrome seems to be further along in implementing SVG 2 than other browsers. The way it is displaying the embedded image would be wrong if it were still supporting only the SVG 1.1 standard.
Firefox (and IE, which is behaving the same) are both incorrect with respect to both SVG 1.1 and SVG 2. The SVG 1.1 standard says that when the SVG file referenced by <image> has no viewBox, it should just be displayed at the position defined by the x and y attributes, and the width and the height of the <image> element is ignored. In other words like this:
<svg viewBox="0 0 200 200" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="0" cy="0" r="80" style="fill:blue" />
<image x="10" y="20" width="335" height="296" xlink:href="https://webkit.org/blog-files/circle.svg" />
</svg>
In any case, there is a simple fix. Add an appropriate viewBox to circle.svg and it will render the same in all browsers, whether they support SVG 2 or not.
<svg xmlns="http://www.w3.org/2000/svg" width="335" height="296" viewBox="0 0 335 296">
I've came across a similar issue where we ended up using the SVG's tag.
This way you will be able to embed an html img tag in it and style it as such. Something like this:
<svg viewBox="0 0 200 200" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="0" cy="0" r="80" style="fill:blue" />
<foreignObject x="10" y="20" width="120" height="150"
requiredExtensions="http://www.w3.org/1999/xhtml">
<body xmlns="http://www.w3.org/1999/xhtml">
<img src="https://webkit.org/blog-files/circle.svg" alt="Smiley face" height="150" width="120">
</body>
</foreignObject>
</svg>
Here is the MDN documentation for
https://developer.mozilla.org/en/docs/Web/SVG/Element/foreignObject

How can I display an SVG image within an <object> tag at a different scale?

How can I display an SVG image within an object tag at a different scale than its original scale?
For example, if I have an SVG file saved as example.svg:
<?xml version="1.0" encoding="UTF-8" ?>
<svg xmlns="http://www.w3.org/2000/svg"
version="1.1"
viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="orange"></circle>
</svg>
and I want to display this in page.html at a different scale:
<!DOCTYPE html>
<html>
<head></head>
<body>
<object type="image/svg+xml" data="/example.svg" width="50" height="50">
</object>
</body>
</html>
It ought to display a version of the svg scaled down to 50x50, but instead it keeps the scale the same and gives the image scrollbars.
However, if I do an inline SVG like the following, it works:
<!DOCTYPE html>
<html>
<head></head>
<body>
<svg xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="50"
height="50"
viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="orange"></circle>
</svg>
</body>
</html>
I have tried various combinations of this, such as adding width="100" and height="100" into the .svg file, using preserveAspectRatio="xMidYMid meet", adding 'px' to the width and height values, using width and height = "100%" in the svg, and other things, but none of them have worked.
In my situation I can just include the svg inline, but I don't feel like it should be that hard to change the scale of the image. Plus I want the browser to be able to cache the image.
SVG is case sensitive. If you change viewbox to the correct case of viewBox in example.svg then this displays as you want it to (at least it does on Firefox and Opera I didn't try other UAs).
You need to set the width and height attributes of your svg element to 100%. It will then be scaled to the size of the container (the object element). Without that, it will just be displayed at the exact size specified (100 pixels).
<?xml version="1.0" encoding="UTF-8" ?>
<svg xmlns="http://www.w3.org/2000/svg"
version="1.1"
viewBox="0 0 100 100"
width="100%" height="100%">
<circle cx="50" cy="50" r="50" fill="orange"></circle>
</svg>
What works for me is the following: I define the "basic" size of the svg with a viewbox and also add the attributes "height=100% width=100%". This means, that the svg will take 100% of the width and height of its parent element. If I put the SVG in an <object> tag, I simply define the size of the object per css and voila, the SVG automagically adapts its size. In the example, I scale an SVG where the viewbox defines a size 100x100px to 300x300px.
file.svg
<svg viewBox="0 0 100 100" width="100%" height="100%">
<path .... />
</svg>
HTML:
<object type="image/svg+xml" data="your/path/to/file.svg" class="icon"></object>
CSS:
object.icon{
height:auto;
width: 300px;
}