All day long I am working on making SVG responsive and reading various articles, and testing different kind of code even in stack overflow.
Unfortunatly I am unsucessful in making my svg expand based on the container div, like I normally do with images when I define max-width:100%
I am using SVG stacks as technique:
http://simurai.com/blog/2012/04/02/svg-stacks/
example of his code: http://jsfiddle.net/simurai/7GCGr/
I noticed that after a certain size of the svg, it doesn't expand anymore and his maximum size become 150px even if I give it 100% as width.
if I force by inserting width & height sizes it grows bigger, but it is not what I want. I want that it resizes ALWAYS based on the width of the container, even becoming something terribly huge without any size limitations.
In the svg the height and width are removed.
My code:
/* RESET - http://meyerweb.com/eric/tools/css/reset/ */
html, body, applet, object, iframe, svg, h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li,
fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, figure{
margin:0; padding:0; border:0; font-size:100%; font-weight:inherit; font-style:inherit;
font-family:inherit; text-decoration:inherit; text-align:left; background:transparent;
}
header, footer, figure, details, hgroup, section, article, nav, aside{display:block;}
img, object, audio, video, svg{width:100%;}
.vector{display:block; width:100%; height:auto;}
.vector embed{border:1px solid #f00; width:100%;}*/
.box{border:1px solid #f00; width:700px;}
<div class="box">
<object class="vector">
<embed src="http://life-is-simple.net/sprite.svg#winner-cup" />
</object>
<img class="vector" src="http://life-is-simple.net/sprite.svg#winner-cup">
<img class="vector" src="http://life-is-simple.net/sprite.svg#lottery-ticket">
<img class="vector" src="http://life-is-simple.net/sprite.svg#monitor-number">
<img class="vector" src="http://life-is-simple.net/sprite.svg#emblem">
</div>
I would really appreciate some help, I do not know what to test anymore to make it work it, especially when I see that simple included svg inserted they do go 100%, I was trying with and techniques but I do not see any difference (only IE behave expanding svg, but firefox and chrome do not)
Scale svg the how to:
You can set the width of the svg container so the image wil scale there after:
This requires:
svg element needs a viewBox
svg element width and height are 100%
.container1 {
border: 1px solid green;
display: inline-block;
width: 100px;
}
.container1 .shape1 {
width: 100%;
}
.container2 {
border: 1px solid green;
display: inline-block;
width: 200px;
}
.container2 .shape2 {
width: 100%;
}
<div class="container1">
width set to 100px
<svg class="shape1" viewBox="0 0 100 100">
<circle fill="#15d" cx="50" cy="50" r="50" />
</svg>
</div>
<div class="container2">
width set to 200px
<svg class="shape2" viewBox="0 0 100 100">
<circle fill="#a2b" cx="50" cy="50" r="50" />
</svg>
</div>
The commen error
This will scale the element but keep the aspect ratio of the <svg> image.
Example:
.text span {
display: inline-block;
border: 1px solid rgba(0,0,0, 0.2);
}
.text span:nth-child(2) {
margin-left: 110px;
}
.container1 {
display: inline-block;
border: 1px solid red;
width: 100px;
height: 200px;
}
.container1 .shape1 {
width: 100%;
height: 100%;
}
.container2 {
margin-left: 100px;
display: inline-block;
border: 1px solid green;
width: 200px;
height: 100px;
}
.container2 .shape2 {
width: 100%;
height: 100%;
}
<div class="text"><span>width set to 100px<br> height set to 200px</span>
<span>width set to 200px
<br>height set to 100px</span><div>
<div class="container1">
<svg class="shape1" viewBox="0 0 100 100">
<circle fill="#15d" cx="50" cy="50" r="50" />
</svg>
</div>
<div class="container2">
<svg class="shape2" viewBox="0 0 100 100">
<circle fill="#a2b" cx="50" cy="50" r="50" />
</svg>
</div>
The elemetent DONT SCALE!
The reason they "dont scale" is as mentioned the aspect ratio
There is actually a property for this: preserveAspectRatio
How do i use this propert?
Wel:
.text span {
display: inline-block;
border: 1px solid rgba(0, 0, 0, 0.2);
}
.text span:nth-child(2) {
margin-left: 110px;
}
.container1 {
display: inline-block;
border: 1px solid red;
width: 100px;
height: 200px;
}
.container1 .shape1 {
width: 100%;
height: 100%;
}
.container2 {
margin-left: 100px;
display: inline-block;
border: 1px solid green;
width: 200px;
height: 100px;
}
.container2 .shape2 {
width: 100%;
height: 100%;
}
<div class="text"><span>width set to 100px<br> height set to 200px</span>
<span>width set to 200px
<br>height set to 100px</span>
</div>
<div class="container1">
<svg class="shape1" viewBox="0 0 100 100" preserveAspectRatio="none">
<circle fill="#15d" cx="50" cy="50" r="50" />
</svg>
</div>
<div class="container2">
<svg class="shape2" viewBox="0 0 100 100" preserveAspectRatio="none">
<circle fill="#a2b" cx="50" cy="50" r="50" />
</svg>
</div>
The reason your image won't scale is because it doesn't have a viewBox.
You are linking to a <g> element. That group is inside an SVG that has a viewBox, but that viewBox won't be used. The browser will look for a viewBox on the outer-most <svg> element. That element doesn't have one.
To prove my point, copy the winner-cup viewBox to the root/outermost <svg> element. The SVG will now scale to 100%.
<svg id="icon" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 971.9 842.9">
As to the reason why it was only scaling to a height of 150px. You will find the answer here:
SVG height percentage not working under Linux browsers?
In your case the parent element is <embed> (and <object>) rather than <body>, but the reason is the same.
Related
I recently used a clip-path to do a decorative image cropping. I created a mask in Inkscape and "ripped" it out of the final svg path, and it worked, except that the mask doesn't stretch to the image size, but stays to the view-box size, since the coordinates in the path are absolute.
section {
width: 320px;
height: 320px;
border: 1px solid black;
}
#clipme {
width: 100%;
height: 100%;
background-color: #FF8864;
clip-path: path('m8.3634 9.8309c68.284-6.1882 39.013 12.331 80.804-1.0687 6.0561-1.9419 18.525 0.77696 32.616 1.0687-19.889 102.68 18.582 69.02 0 110.1-42.039-3.5946-82.783-33.22-113.42 0-27.365-85.399 32.654-92.947 0-110.1z');
}
<section>
<div id='clipme'/>
</section>
Is it possible to fix this at the css level? Maybe there are tools that can convert absolute values to relative values? And since I mentioned inkscape, maybe I can configure it there?
Use it as mask instead. Put the path inside an SVG with the correct viewBox then load it like an image. Resize the section element to see the effect
section {
width: 320px;
height: 320px;
border: 1px solid black;
overflow: auto;
resize: both;
}
#clipme {
width: 100%;
height: 100%;
background-color: #FF8864;
-webkit-mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 130 130"><path d="M8.3634 9.8309c68.284-6.1882 39.013 12.331 80.804-1.0687 6.0561-1.9419 18.525 0.77696 32.616 1.0687-19.889 102.68 18.582 69.02 0 110.1-42.039-3.5946-82.783-33.22-113.42 0-27.365-85.399 32.654-92.947 0-110.1zz"></path></svg>' ) center/contain no-repeat
}
<section>
<div id='clipme'></div>
</section>
I have a colored div followed by an svg. When changing my browser window, sometimes a small white line appears. How can I get rid of it?
.wave {
background-image: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="red" d="M0,96L80,85.3C160,75,320,53,480,90.7C640,128,800,224,960,266.7C1120,309,1280,299,1360,293.3L1440,288L1440,0L1360,0C1280,0,1120,0,960,0C800,0,640,0,480,0C320,0,160,0,80,0L0,0Z"/></svg>');
height:180px;
background-size:100%;
background-repeat: no-repeat;
margin-top:-20px;
background-color:white;
}
<div style="background-color:red;width:100%;height:100px">
</div>
<div class="wave">
hallo
</div>
These are rounding artefacts that cannot be avoided. background-color:white introduces a white rectangle behind the svg, but on top of the top div that might be slightly too large. Remove it, and the svg content will sit directly on top of the div.
If you need an explicitely white background, apply it to an element that sits behind both the top div and the svg. For example like this, avoiding an extra DOM object:
.top {
position: relative;
background-color:red;
width:100%;
height:100px;
}
.top::after {
content: "";
position: absolute;
top: 100%;
width:100%;
height:180px;
z-index: -1;
background-color:white;
}
.wave {
background-image: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="red" d="M0,96L80,85.3C160,75,320,53,480,90.7C640,128,800,224,960,266.7C1120,309,1280,299,1360,293.3L1440,288L1440,0L1360,0C1280,0,1120,0,960,0C800,0,640,0,480,0C320,0,160,0,80,0L0,0Z"/></svg>');
height:180px;
background-size:100%;
background-repeat: no-repeat;
margin-top:-20px;
}
<div class="top">
</div>
<div class="wave">
hallo
</div>
While replacing some .png icons to .svg I'd run onto some problem, consider this:
<div class="container"></div>
.container {
width: 100px;
height: 100px;
background-image: url("some-image.png");
background-size: cover;
transition: 1s;
}
In this case I had applied CSS transition to container and change its size (enlarge). Image inside the container onenlarge scales from center point inline with the container.
But when I changed it to .svg code (bellow) it starts to scaling from the left top corner. Does it possible to make it scale from the center of the container with my current set up (or at all)?
<div class="container"> <svg></svg> </div>
.container {
width: 100px;
height: 100px;
transition: 1s;
}
// I already tried play with transform-origin all the way possible, applying it to the container/svg tag/and all elements inside it...
This is not an answer but I need to add some code. I don't see any difference. Please take a look. First I'm using two elements image.
.container {
position: absolute;
top: 0;
width: 100px;
height: 100px;
border: 1px solid;
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/apple.png");
background-size: cover;
transition: 1s;
}
.svg {
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/apple.svg");
left: 250px;
}
.container:hover {
width: 200px;
height: 200px;
}
<div class="container"></div>
<div class="container svg"></div>
The second attempt: this time I'm using an svg element instead of a background image for the second div. No difference either.
.container {
position: absolute;
top: 0;
width: 100px;
height: 100px;
border: 1px solid;
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/apple.png");
background-size: cover;
transition: 1s;
overflow:hidden;
}
.svg {
background:black;
left: 250px;
}
.container:hover {
width: 200px;
height: 200px;
}
<div class="container"></div>
<div class="container svg">
<svg viewBox="41 54 106 122">
<g>
<path fill="#FFFFFF" stroke="#ED1D24" stroke-width="2" stroke-miterlimit="10" d="M143.099,93.757c0,0-14.173,8.549-13.724,23.173 c0.449,14.624,11.954,23.413,15.974,24.073c1.569,0.258-9.245,22.049-15.984,27.448c-6.74,5.4-13.714,6.524-24.513,2.25c-10.8-4.275-18.449,0.275-24.749,2.612c-6.299,2.337-13.949-0.137-24.298-14.987c-10.349-14.849-21.823-49.271-6.074-66.146c15.749-16.874,33.298-10.124,38.022-7.875c4.725,2.25,13.05,2.025,22.499-2.25C119.7,77.782,138.374,86.782,143.099,93.757z"/>
</g>
<g>
<path fill="#FFFFFF" stroke="#ED1D24" stroke-width="2" stroke-miterlimit="10" d="M118.575,54.609c0,0,0.9,5.625-1.35,10.349
s-10.718,20.936-22.994,17.999c-0.308-0.073-2.102-5.506,0.532-11.027C98.48,64.138,108.171,55.399,118.575,54.609z"/>
</g>
</svg>
</div><div class="container"></div>
<div class="container svg">
<svg viewBox="41 54 106 122">
<g>
<path fill="#FFFFFF" stroke="#ED1D24" stroke-width="2" stroke-miterlimit="10" d="M143.099,93.757c0,0-14.173,8.549-13.724,23.173 c0.449,14.624,11.954,23.413,15.974,24.073c1.569,0.258-9.245,22.049-15.984,27.448c-6.74,5.4-13.714,6.524-24.513,2.25c-10.8-4.275-18.449,0.275-24.749,2.612c-6.299,2.337-13.949-0.137-24.298-14.987c-10.349-14.849-21.823-49.271-6.074-66.146c15.749-16.874,33.298-10.124,38.022-7.875c4.725,2.25,13.05,2.025,22.499-2.25C119.7,77.782,138.374,86.782,143.099,93.757z"/>
</g>
<g>
<path fill="#FFFFFF" stroke="#ED1D24" stroke-width="2" stroke-miterlimit="10" d="M118.575,54.609c0,0,0.9,5.625-1.35,10.349
s-10.718,20.936-22.994,17.999c-0.308-0.073-2.102-5.506,0.532-11.027C98.48,64.138,108.171,55.399,118.575,54.609z"/>
</g>
</svg>
</div>
Maybe you should edit your question and add more detail
I found the problem as well as the solution
All seems fine when animating only height and width, but some of my icons have top and left properties to animate to. And these ones are cousins the problem.
In my case it was looked like the svg is constantly "jumps" to the upper left corner while its container was resizing, but actually it was just snapping to the whole pixel value.
Animation of top/left properties are not subpixel, so in order to animate it smoothly it is better to animate X and Y, instead of manipulating them directly.
When I did so, the problem was gone.
Try to use the CSS attribute transform-origin see here
div {
transform-origin: 50% 50%;
}
transform-origin: 50% 50%; should center it.
I am trying to add dashed border top on a div using css. I have this:
https://jsfiddle.net/uexma4o6/74/
div {
display: inline-block;
width: 50px;
height: 50px;
border-top: 2px dashed #AAA;
}
The problem is that first and last dash are little longer than others. I think it's because actual borders on the left and right are included? How can I make all dashes same width? I am looking for solution without using border-image. Thanks.
Try this. you can adjust the size and width based on your requirement.
background-image: linear-gradient(to right, white 33%, rgba(255,255,255,0) 0%);
background-position: top;
background-size: 5px 3px;
background-repeat: repeat-x;
border-right-width: 2px;
You could use a SVG line within your div like -
<div>
<svg width="50" height="2" viewBox="0 0 50 2" xmlns="http://www.w3.org/2000/svg">
<line x1="0" y1="0" x2="50" y2="0" stroke-width="2" stroke="#AAA" stroke-dasharray="2" stroke-width="2"/>
</svg>
</div>
I'm setting an svg as a background image for a div (set as a table-cell, but now it's not the point). It stretches to fit the space, and that's what I wanted, and I set some padding (IN % units) to keep the text inside the image. Now the problem is that scaling the viewport or just changing the height of the div padding and image height change differently so the text positioning is scrambled. Here is the css code:
#contenuto {
border: 0px solid;
width: 79%;
display: table-cell;
font-size: 1.0em;
padding-top: 1.5%;
padding-bottom: 1.5%;
padding-right: 5%;
padding-left: 7%;
background: url(./pic/template.svg) no-repeat;
background-size: auto 100%;
background-position:center center;
background-origin: border-box;
}
the svg file is properly set I guess:
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 400 640" preserveAspectRatio="none">
What can I do to fix?