SVG appearing outside of viewport - html

I've tried to make the SVG viewport take up 100% of the width and height of the page here:
http://jsfiddle.net/XZ57u/2/
However it seems to appear only when I change this:
<svg 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 100 100" enable-background="new 0 0 100 100" xml:space="preserve" id="city">
To this (viewport size):
<svg 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 1400 1400" enable-background="new 0 0 1400 1400" xml:space="preserve" id="city">
My understanding was that the 100 meant it was taking up the whole viewport percentage so why then does it appear off the page?

viewBox="0 0 100 100"
Simply put viewbox defines the coordinate-system limits of your SVG...it has nothing (really) to do with the dimensions of the element in the HTML which you can either set in the SVG itself or in your CSS.
By changing the viewbox you are effectively saying, I only want to see the top left 100x100 section of my 1400x1400 SVg.
EDIT: JSfiddle demo
with original 1400 viewbox and any CSS dimensions.

The viewbox numbers stand for pixels, not for percentatge. If you want to cover the whole container you have to set the SVG elements width and height to 100%
use this instead:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="100%" y="100%" xml:space="preserve" id="city">
here is the fiddle: http://jsfiddle.net/t5rhp/

you have to define the viewBox attribute as well. In addition you could also use Preserving Aspect Ratio as well.
svg {
width:100%;
height:100%;
}
<svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid none">
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>

Related

How can I make the path element the same width of my svg element?

I have a chevron svg on my site but the positioning is making the page wider than I need it. So I was looking at the elements and noticed the path is much skinnier than the actual svg element.
I want the width of the whole svg element to be only the width needed for the size of the chevron, I can supply the svg code.
<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"
viewBox="0 0 512.001 512.001" style="enable-background:new 0 0 512.001 512.001;" xml:space="preserve">
<path style="fill:#FFF;" d="M388.819,239.537L156.092,6.816c-9.087-9.089-23.824-9.089-32.912,0.002
c-9.087,9.089-9.087,23.824,0.002,32.912l216.27,216.266L123.179,472.272c-9.087,9.089-9.087,23.824,0.002,32.912
c4.543,4.544,10.499,6.816,16.455,6.816c5.956,0,11.913-2.271,16.457-6.817L388.819,272.45c4.366-4.364,6.817-10.283,6.817-16.455
C395.636,249.822,393.185,243.902,388.819,239.537z"/>
</svg>
You can just take BBox and redefine viewBox attribute by the data:
const svg = document.querySelector('svg');
const path = svg.querySelector('path');
const box = path.getBBox();
svg.setAttribute('viewBox', `${box.x} ${box.y} ${box.width} ${box.height}`);
<svg viewBox="0 0 512.001 512.001" style="background: gray; width: 100px">
<path style="fill:#FFF;" d="M388.819,239.537L156.092,6.816c-9.087-9.089-23.824-9.089-32.912,0.002
c-9.087,9.089-9.087,23.824,0.002,32.912l216.27,216.266L123.179,472.272c-9.087,9.089-9.087,23.824,0.002,32.912
c4.543,4.544,10.499,6.816,16.455,6.816c5.956,0,11.913-2.271,16.457-6.817L388.819,272.45c4.366-4.364,6.817-10.283,6.817-16.455
C395.636,249.822,393.185,243.902,388.819,239.537z"/>
</svg>
You would either have to adjust the path to fit the current viewbox or adjust the viewbox to the current path.
The latter would be approximately like this:
viewBox="117 0 280 512.001"
svg {
border: 1px solid red;
height: 90vh;
margin: 4px;
}
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="117 0 280 512.001" style="enable-background:new 0 0 512.001 512.001;" xml:space="preserve">
<path d="M388.819,239.537L156.092,6.816c-9.087-9.089-23.824-9.089-32.912,0.002
c-9.087,9.089-9.087,23.824,0.002,32.912l216.27,216.266L123.179,472.272c-9.087,9.089-9.087,23.824,0.002,32.912
c4.543,4.544,10.499,6.816,16.455,6.816c5.956,0,11.913-2.271,16.457-6.817L388.819,272.45c4.366-4.364,6.817-10.283,6.817-16.455
C395.636,249.822,393.185,243.902,388.819,239.537z"/>
</svg>

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>

Manipulate svg colors with css

I have made a svg icon for search in illustrator, and want to use it in my website. I have place it in the html can see the icon.
<div id="search-btn">
<img src="svg/search.svg">
</div>
But since I made it in black, I want to change the color of the magnifiying glass and the background. How do I manipulate the colors of the svg using css? I am very new to svg and your help will be very valuable. Thank you.
search icon:
svg code:
<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"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<path id="XMLID_10_" d="M98.2,89.7L63,54.5c-0.1-0.1-0.1-0.1-0.2-0.2c4-5.6,6.3-12.4,6.3-19.8c0-19-15.4-34.4-34.4-34.4
c-19,0-34.4,15.4-34.4,34.4c0,19,15.4,34.4,34.4,34.4c7.3,0,14-2.3,19.6-6.1c0.1,0.1,0.1,0.2,0.2,0.3l35.2,35.2
c2.4,2.4,6.2,2.4,8.5,0l0,0C100.6,95.9,100.6,92.1,98.2,89.7z M7.3,34.5c0-15.1,12.3-27.4,27.4-27.4c15.1,0,27.4,12.3,27.4,27.4
c0,15.1-12.3,27.4-27.4,27.4C19.6,61.9,7.3,49.6,7.3,34.5z"/>
</svg>
As said in the comments on this answer
CSS does not apply cross-document and the img is a separate document.
Images must be self contained in a single file to preserve privacy. –
Robert Longson
So this means you won't be able to include your SVG in your img tag and customize it using CSS on the page. So you have two options:
Inline the SVG code, which means scrapping the img tag. You can then target the SVG as below.
#search-btn svg {
fill: blue;
background: grey;
width: 100px;
}
<div id="search-btn">
<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" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<path id="XMLID_10_" d="M98.2,89.7L63,54.5c-0.1-0.1-0.1-0.1-0.2-0.2c4-5.6,6.3-12.4,6.3-19.8c0-19-15.4-34.4-34.4-34.4
c-19,0-34.4,15.4-34.4,34.4c0,19,15.4,34.4,34.4,34.4c7.3,0,14-2.3,19.6-6.1c0.1,0.1,0.1,0.2,0.2,0.3l35.2,35.2
c2.4,2.4,6.2,2.4,8.5,0l0,0C100.6,95.9,100.6,92.1,98.2,89.7z M7.3,34.5c0-15.1,12.3-27.4,27.4-27.4c15.1,0,27.4,12.3,27.4,27.4
c0,15.1-12.3,27.4-27.4,27.4C19.6,61.9,7.3,49.6,7.3,34.5z" />
</svg>
</div>
Or you could add styles to the SVG file itself, as below, but this is similar to simply editing the file in Illustrator to get the colours you want.
<div id="search-btn">
<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" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<defs>
<style>
#XMLID_10_ {
fill: blue;
}
</style>
</defs>
<path id="XMLID_10_" d="M98.2,89.7L63,54.5c-0.1-0.1-0.1-0.1-0.2-0.2c4-5.6,6.3-12.4,6.3-19.8c0-19-15.4-34.4-34.4-34.4
c-19,0-34.4,15.4-34.4,34.4c0,19,15.4,34.4,34.4,34.4c7.3,0,14-2.3,19.6-6.1c0.1,0.1,0.1,0.2,0.2,0.3l35.2,35.2
c2.4,2.4,6.2,2.4,8.5,0l0,0C100.6,95.9,100.6,92.1,98.2,89.7z M7.3,34.5c0-15.1,12.3-27.4,27.4-27.4c15.1,0,27.4,12.3,27.4,27.4
c0,15.1-12.3,27.4-27.4,27.4C19.6,61.9,7.3,49.6,7.3,34.5z" />
</svg>
</div>
To set the background-color of your <svg> you have to use the background or background-color property. To set the color of the icon you have to use the fill property. See the following example:
svg {
background:yellow;
fill:red;
}
<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"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<path id="XMLID_10_" d="M98.2,89.7L63,54.5c-0.1-0.1-0.1-0.1-0.2-0.2c4-5.6,6.3-12.4,6.3-19.8c0-19-15.4-34.4-34.4-34.4
c-19,0-34.4,15.4-34.4,34.4c0,19,15.4,34.4,34.4,34.4c7.3,0,14-2.3,19.6-6.1c0.1,0.1,0.1,0.2,0.2,0.3l35.2,35.2
c2.4,2.4,6.2,2.4,8.5,0l0,0C100.6,95.9,100.6,92.1,98.2,89.7z M7.3,34.5c0-15.1,12.3-27.4,27.4-27.4c15.1,0,27.4,12.3,27.4,27.4
c0,15.1-12.3,27.4-27.4,27.4C19.6,61.9,7.3,49.6,7.3,34.5z"/>
</svg>
You could use classes for svg elements.
Adobe Illustrator for example offers the possibility to create SVG internal CSS.
But you can also write the style definitions in your own stylesheet.
To set the background use the fill property, like sebastianbrosch mentioned.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300">
<defs>
<style>
.orange {
fill:#f66d00;
}
</style>
</defs>
<path class="orange" d="M98.2, ... ,34.5z"/>
</svg>

SVG path background image autoscale with aspect-ratio

I want to fill a path in my svg with a background image, that autoscales to fill the entire path while maintaining the aspect-ratio of the image, thus as if you'd use the css background-size: cover, I've managed to get this working with clipPath or making a pattern from the image (would also like to know which of these is the option with best browser support) but I can't get the auto scaling to use.
If anyone would have some tips or solutions I would appreciate.
Here's a jsfiddle with an example of what i've got to work.
https://jsfiddle.net/shd50cvt/
The svg:
<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="341.722px" height="267.549px" viewBox="0 0 341.722 267.549" style="enable-background:new 0 0 341.722 267.549;"
xml:space="preserve">
.st0{fill:#FF0000;}
.st1{fill: url(#pattern);}
In the pattern element, you can use patternUnits="objectBoundingBox" and x="0" and y="0" and width="1" and height="1" to auto scale a single pattern tile to the size of the path. You can use preserveAspectRatio="xMidYMid slice" to maintain the aspect ratio of the tile while covering the entire path. You may need to also set preserveAspectRatio on the image element in case the jpg size does not match the image element size.
Refer to the SVG reference for more information on patterns.
http://www.w3.org/TR/SVG/pservers.html#Patterns
I have modified your example to scale the image to fill the path.
<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="341.722px" height="267.549px" viewBox="0 0 341.722 267.549" style="enable-background:new 0 0 341.722 267.549;"
xml:space="preserve">
<pattern id="pattern" patternUnits="objectBoundingBox" preserveAspectRatio="xMidYMid slice"
x="0" y="0" width="1" height="1" viewbox="0 0 400 300">
<image xlink:href="https://static.pexels.com/photos/909/flowers-garden-colorful-colourful.jpg"
x="0" y="0" width="400" height="300" preserveAspectRatio="xMidYMid slice"/>
</pattern>
<style type="text/css">
.st0{fill:#FF0000;}
.st1{fill: url(#pattern);}
</style>
<path class="st1" d="M199.668,52.98c-17.815,0-32.711,12.454-36.484,29.128c23.783,3.473,43.093,20.685,49.641,43.322
c14.174-5.325,24.262-18.998,24.262-35.033C237.086,69.732,220.334,52.98,199.668,52.98z"/>
<circle class="st0" cx="154.305" cy="142.384" r="60.927"/>
</svg>

My svg circle repeats image background

What am I doing wrong ? The background doesn't set properly.
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1101px" height="617px" viewBox="0 0 1101 617" enable-background="new 0 0 1101 617" xml:space="preserve">
<defs>
<pattern id="image" patternUnits="userSpaceOnUse" height="150" width="150">
<image x="30" y="0" height="150" width="150" xlink:href="http://i.imgur.com/7Nlcay7.jpg"></image>
</pattern>
</defs>
<circle fill="url(#image)" stroke="#676467" stroke-width="3" stroke-miterlimit="10" cx="186.051" cy="489.94" r="63.29"/>
</svg>
Sample:
http://prntscr.com/amjogg
You are using the image as a fill pattern, so it doesn't stretch or anything. You use x and y in the image to set the image position in the pattern, which can set a padding in the pattern so to speak. Then the pattern gets applied.
In your case you have a 150x150 pattern with a 150x150 image that is offset 30 pixels to the right, so the pattern looks like 120 pixels of image with a 30 pixel white padding to the left.
Without knowing what your intention was, I don't know what "properly" means in your context.