How to make irregularly-shaped SVGs overlap while maintaining all areas clickable? - html

I have created 4 SVGs (all same shapes) that are floated to the left. I have tried to make them overlap (as it looks nicer that way) but the problem is that since their shapes are irregular, some areas become un-clickable.
I used this as the CSS code:
.interact-arrow {
float: left;
margin-right: -100px;
width: 24%;
position: relative;
}
This is the complete codepen demo of the problem: http://codepen.io/aguerrero/pen/pgvJoa
How do I properly code the CSS so that I can click on any area of the individual arrows? I'm using <image> inside the <svg> as the clickable area.

You need to apply CSS classes directly to your SVG.
See the SVG tags need to be sisters
Example:
<div class="wrapper-interact-arrow">
<svg class="interact-arrow button-reverse">
...
</svg>
<svg class="interact-arrow button-play">
...
</svg>
<svg class="interact-arrow button-pause">
...
</svg>
<svg class="interact-arrow button-arrow">
...
</svg>
See the example: http://codepen.io/anon/pen/dGMmaY

Related

SVG Sprite in css declared background image [duplicate]

I know external svg files can be linked to background images:
background-image: url(Icon.svg);
and symbols id's can be targeted from an external svg file:
background-image: url(Icons.svg#Icon-Menu);
but how can I set a background image to an inline svg symbol? (As below)
My svg is at the top of my web page body and not in an external file.
I want .test background image to be the #Icon-Menu symbol.
.test{
background:#ddd url('../#Icon-Menu');
height:100px;
width:100px;
display:block;
}
<div style="height: 0; width: 0; position: absolute; visibility: hidden;">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="Icon-Menu" viewBox="0 0 512 512">
<title>Menu</title>
<path d="M93.417,5.333H6.583c-1.654,0-3,1.346-3,3v13.334c0,1.654,1.346,3,3,3h86.833c1.654,0,3-1.346,3-3V8.333 C96.417,6.679,95.071,5.333,93.417,5.333z" />
<path d="M93.417,40.333H6.583c-1.654,0-3,1.346-3,3v13.334c0,1.654,1.346,3,3,3h86.833c1.654,0,3-1.346,3-3V43.333 C96.417,41.679,95.071,40.333,93.417,40.333z" />
<path d="M93.417,75.333H6.583c-1.654,0-3,1.346-3,3v13.334c0,1.654,1.346,3,3,3h86.833c1.654,0,3-1.346,3-3V78.333 C96.417,76.679,95.071,75.333,93.417,75.333z" />
</symbol>
</svg>
</div>
<div class="test"></div>
#Robert Longson
thats right. But you can do it this way.
But symbol is not the way it will work. Unfortunatly you have to use "g" or something like that to reference.
body {
background: url(http://www.broken-links.com/tests/images/faces.svg#devil-view);
}
http://codepen.io/Type-Style/pen/ByvKJq
It will not work if the svg is in the Markup.
An image must be a complete file.
From the SVG specification...
The ‘image’ element indicates that the contents of a complete file are to be rendered...
The same is true for background-image etc.
(1) one possible way with inline SVG would be to use symbols and DIV absolute layering:
<a class="preview-modal__device-icon-link" ng-click="setPreviewWidth('phone')">
<svg class="preview-modal__device-icon"><use xlink:href="#icon-phone">
</use></svg>
</a>
(2) Second solution would be to use a Data URI:
there is a good info here: https://css-tricks.com/using-svg/
using this tool: Mobilefish.com online conversion tool
CSS:
.logo {
background: url("data:image/svg+xml;base64,[data]");
}
HTML:
<img src="data:image/svg+xml;base64,[data]">

Wavy border separator on two sections with [background] images

I’ve been strugglin on making a wavy line on the transition between two sections on my page. These two sections have their respective background images. What I’ve found are examples where at least one section have a simple colored background.
The problem is that when using some of the methods found (svg, clip-path, transform), I have to always fill with a color.
What I want: https://imgur.com/R1sXk8y
What I have done so far: https://imgur.com/CtVLOE8 (This one is a sloped line example. I have to do various shapes on different borders, but its an example to show the separation that would be noticed with the wavy border too)
This is my solution: I'm using clip-path as you intended, although, as you may know, clip-path is not supported in all browsers.
The main idea is having clipPathUnits="objectBoundingBox".
MDN quote:
This value [clipPathUnits="objectBoundingBox"] indicates that all coordinates inside the element are relative to the bounding box of the element the clipping path is applied to. It means that the origin of the coordinate system is the top left corner of the object bounding box and the width and height of the object bounding box are considered to have a length of 1 unit value.
*{margin:0;padding:0;}
#top {
padding: 0;
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/castell.jpg);
background-size: cover;
height: 50vh;
-webkit-clip-path: url(#clip);
clip-path: url(#clip);
}
body{background:url(https://images.unsplash.com/photo-1470327500070-4857199b1bcd?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ);background-size:cover}
<svg height="0" width="0" class="svg-clip" style="position:absolute">
<defs>
<clipPath id="clip" clipPathUnits="objectBoundingBox">
<path d="M0,0 L0,.5 Q.3,.2 .5,.5 T1,.5L1,0 0,0" />
</clipPath>
</defs>
</svg>
<div id="top"></div>

Using a .svg file in HTML from a URL?

I am trying to use an svg from an external source in my html. Let's say I have this svg:
https://upload.wikimedia.org/wikipedia/commons/0/09/America_Online_logo.svg
I found many ways to do this, including:
<img src="your.svg"/> 
<object data="your.svg"/> 
<iframe src="your.svg"/> 
<embed src="your.svg"/> 
<div style="background:url(your.svg)">...</div>
But unfortunately, the styling I have to use applies to svg tags. If I use this for example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image xlink:href="https://upload.wikimedia.org/wikipedia/commons/0/09/America_Online_logo.svg"/>
</svg>
It won't show up on my page, I just get an empty white square! Is there anyway I can do this inside svg tags? Thanks!
You have to specify a width and height for your svg to display properly:
<svg width="90" height="90">
<image xlink:href="your.svg" src="yourfallback.png" width="90" height="90"/>
</svg>
Update
You can do this via CSS too of course, but you have to be sure that your <image> tag has width and height set in your CSS if you don't specify the html attributes directly:
svg {
width: 150px;
height: 150px;
}
image {
width: 100px;
height: 100px;
}
This will set the size of your actual image (the svg) to 100px * 100px, but has a "wrapper" of 150px. Regarding to your comment to your original question, maybe that's why you don't see your image, because you dont have set a width / height and only styles which apply to your wrapping element (<svg>)
Example Fiddle: https://jsfiddle.net/7334vrmq/
Hope this helps.

Setting a css background image to an inline SVG symbol?

I know external svg files can be linked to background images:
background-image: url(Icon.svg);
and symbols id's can be targeted from an external svg file:
background-image: url(Icons.svg#Icon-Menu);
but how can I set a background image to an inline svg symbol? (As below)
My svg is at the top of my web page body and not in an external file.
I want .test background image to be the #Icon-Menu symbol.
.test{
background:#ddd url('../#Icon-Menu');
height:100px;
width:100px;
display:block;
}
<div style="height: 0; width: 0; position: absolute; visibility: hidden;">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="Icon-Menu" viewBox="0 0 512 512">
<title>Menu</title>
<path d="M93.417,5.333H6.583c-1.654,0-3,1.346-3,3v13.334c0,1.654,1.346,3,3,3h86.833c1.654,0,3-1.346,3-3V8.333 C96.417,6.679,95.071,5.333,93.417,5.333z" />
<path d="M93.417,40.333H6.583c-1.654,0-3,1.346-3,3v13.334c0,1.654,1.346,3,3,3h86.833c1.654,0,3-1.346,3-3V43.333 C96.417,41.679,95.071,40.333,93.417,40.333z" />
<path d="M93.417,75.333H6.583c-1.654,0-3,1.346-3,3v13.334c0,1.654,1.346,3,3,3h86.833c1.654,0,3-1.346,3-3V78.333 C96.417,76.679,95.071,75.333,93.417,75.333z" />
</symbol>
</svg>
</div>
<div class="test"></div>
#Robert Longson
thats right. But you can do it this way.
But symbol is not the way it will work. Unfortunatly you have to use "g" or something like that to reference.
body {
background: url(http://www.broken-links.com/tests/images/faces.svg#devil-view);
}
http://codepen.io/Type-Style/pen/ByvKJq
It will not work if the svg is in the Markup.
An image must be a complete file.
From the SVG specification...
The ‘image’ element indicates that the contents of a complete file are to be rendered...
The same is true for background-image etc.
(1) one possible way with inline SVG would be to use symbols and DIV absolute layering:
<a class="preview-modal__device-icon-link" ng-click="setPreviewWidth('phone')">
<svg class="preview-modal__device-icon"><use xlink:href="#icon-phone">
</use></svg>
</a>
(2) Second solution would be to use a Data URI:
there is a good info here: https://css-tricks.com/using-svg/
using this tool: Mobilefish.com online conversion tool
CSS:
.logo {
background: url("data:image/svg+xml;base64,[data]");
}
HTML:
<img src="data:image/svg+xml;base64,[data]">

How to fix SVG top and left stroke truncation?

I have created an ellipse in SVG with a stroke-width and stroke but the top and left sides of the stroke are truncated. They appear to be overflowing outside of the containing svg tag. I tried using overflow:visible; property on the SVG but it still doesn't work.
Following is my HTML:
<div id="div1">
<svg id="svg1">
<ellipse id="oval1" cx="164.041666625656" cy="96.1319444204114" rx="164.041666625656" ry="96.1319444204114"></ellipse>
</svg>
</div>
And this is its CSS:
#div1 {
padding:10px;
margin:10px;
}
#svg1 {
overflow:visible;
margin-left:86.4305555339479;
margin-top:-4.409722221119791;
}
#oval1 {
fill:hsl(50.7692307692305,27.6595744680847%,68.0882352941177%);
stroke-width:5.291666665343749;
stroke:hsl(79.5918367346938,41.8803418803418%,40.5882352941176%);
}
You can see the running code here as well.
I have had a similar problem with rectangles in the past and they got fixed after using overflow:visible; for the containing svg. But it doesn't seems to be working for ellipses now.
Can anyone help me fix the issue?
Thnx in advance!
UPDATE: Looks like there are active bug for this behaviour in at least Chrome (https://code.google.com/p/chromium/issues/detail?id=231577) and has been for Firefox as well (https://bugzilla.mozilla.org/show_bug.cgi?id=378923). So depending on version you might be out of luck. As of writing this is not fixed in Chrome (32.0.1700.6 beta) and there is a fiddle you can use to test with here: http://jsfiddle.net/HRsvX/36/ all three triangles should be fully visible if the browser implements the current SVG 1.1 spec. Fiddle reproduced below.
The circle inner area is bordering the SVG element. Before HTML5t the SVG element itself is like an image or flash movie, it can't overflow into the html document, it has it's own canvas so to speak. When you add stroke (that by default is outside the area you defined) the stroke will end up outside the SVG canvas. You'll have to account for that in the centering of the circle:
The center has to be the radius+stroke width so your center x for example would have to be 164.041666625656 + 5.291666665343749 minimum to fully fit inside the SVG.
If you specify the HTML5 doctype and use an inline SVG as in your example it should show the overflowing content since the default value for overflow is visible and HTML5 allows for overflow on inline SVG elements.
So either check your doctype or reposition the center to account for the stroke width.
More on the overflow of SVG elements can be found in Mozilla developer documents and a nice piece on this MSDN blog that explains the default overflow.
HTML
<div><svg height="100" width="100" viewbox="00 0 100 100">
<path d="M210 10 L90 10 L90 90 " fill="red"/>
</svg></div>
<div><svg id="clip1" height="100" width="100" viewbox="00 0 100 100">
<path d="M210 10 L90 10 L90 90 " fill="red"/>
</svg></div>
CSS
div {
height:100px; width:100px;
margin:1em auto;
border: solid 1px black;
}
svg { overflow:visible }
#clip1 {clip: rect(-10px,-10px,-10px,-10px)} //nope
#clip2 {clip: auto} //nope
Add a viewBox that describes the content of the SVG. The browser will then ensure that the entire ellipse and its stroke are visible. If you want it renderered at 1:1, you will also need to add an equivalent width and height.
<svg id="svg1" width="335" height="199" viewBox="-3 -3 335 199">
<ellipse id="oval1" cx="164.041666625656" cy="96.1319444204114" rx="164.041666625656" ry="96.1319444204114" />
</svg>
Demo here