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>
Related
I see that you can reference the svg by id in some css/svg properties, as in:
<!-- the logo svg -->
<svg id="rect-container" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- left squares -->
<rect fill="url(#rect-fill)"/>
</svg>
does anyone know if we can use a svg from the page, in a css bg for example? to avoid encoding it on the css.
Something like this, which I already tried but did not seem to work the same way.
.myel {
background-image: url(#rect-svg-image);
}
First, there is a misconception to clear up.
fill: url(#source);
does not reference arbitrary SVG content, but a paint server, namely a gradient or pattern. Other uses of the CSS url() notation in SVG include the clip-path, mask and marker-start|mid|end properties that all also can only reference specific elements.
Currently, background-image needs an actual self-contained image resource or a CSS gradient. Referencing a SVG paint server with url() does not work.
But the CSS Images Module Level 4 also defines a element() functional notation that can reference fragments inside the page.
If you look at the text of the specification, there are still a lot of open questions listed to solve before this can become mainstream. There currently is only a Firefox implementation with vendor prefix, -moz-element(). You can point it to paint servers; that means you can (mis)use a <pattern> element. Although experimenting, I found there are some tradeoffs to make:
patternContentUnits="objectBoundingBox" needs all content drawn into a 1px*1px square, but makes the content scalable. Preserving the aspect ratio is not supported.
patternContentUnits="userSpaceOnUse" gives you preservation of the aspect ratio, but scaling is not supported.
svg {
display: block;
width: 0;
height: 0;
}
div {
width: 200px;
height: 150px;
border: 1px solid black;
background-image: -moz-element(#image);
background-size: cover;
}
<svg>
<pattern patternContentUnits="objectBoundingBox"
preserveAspectRatio="xMidYMid meet"
width="100%" height="100%" id="image">
<rect width=".5" height=".5" fill="red"/>
<rect width=".5" height=".5" x=".5" fill="yellow"/>
<rect width=".5" height=".5" y=".5" fill="green"/>
<rect width=".5" height=".5" x=".5" y=".5" fill="blue"/>
<circle r=".5" cx=".5" cy=".5" fill="white" opacity=".5"/>
</pattern>
</svg>
<div>
This question already has answers here:
Percentage Height HTML 5/CSS
(7 answers)
Closed 3 months ago.
I'm trying to understand why my SVG will resize when I change the width of its parent but it won't resize when I change the height.
I just made a very simple jsFiddle. You can try resizing the little window at the bottom right corner.
From what I understand, it's key that the parent has 100% width and height so that a window resize is detected and inner svg can adjust. It's also key to specify the viewBox attribute to allow the svg to resize according to its parent div.
But why is it not resizing accorindg to height?
div {
height: 100%;
width: 100%;
}
<div>
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<circle cx="100" cy="100" r="100" />
</svg>
</div>
http://jsfiddle.net/7dz60fkh/
You need to give the html, body and svg elements the same percentage sizes too so they all resize in lock step.
div, html, body, svg {
height: 100%;
width: 100%;
}
<div>
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<circle cx="100" cy="100" r="100" />
</svg>
</div>
SVGs are way more different than pixel images such as jpeg, png ..etc.
The hard part is that you shouldn't think of them like you would with "normal" images, to make things short SVG aren't IMAGES but DOCUMENTS that contains info.
When you include an HTML file with an , you don’t expect the
text inside to scale when you change the size of the frame. Same with
SVG. By default, it will be drawn at the size specified in the code,
regardless of the size of the canvas.
If your svg has something called a viewbox ( which is your case ) then it will be scaled to fit it's defined viewport so increasing the height of the img won't make the icons any taller. You'll just end up with the img in a wider box.
I think mainly your problem is that your SVG have fixed values defined in them. Open up the SVG files and make sure they either:
have no width and height defined, OR have width and height both set to "100%".
you can read more about SVGs in this article, it'll help you understand how things work hopefully
I want to place an image to a position.
<svg width="100%" height="100%">
<image x="100" y="100" width="50" href="..."></image>
... other elements
</svg>
The origin of an image is the top left corner, thus images are placed like the red on in the example below. However, I want the bottom center to be at that position.
The width is fix, so I can easly retrieve half of it to the x coordinate, having the image horizontaly aligned. But the height can vary. I tried
transform: translate(0, -100%)
But this result in translating 100% of the parent svg height, and not it own height.
I'm thinking about opening the file and reading it height, but it is quite expensive. Is there other solutions ?
Actual result (Red) and goal (Green)
Add transform-box: fill-box; as a CSS property to the image.
<svg width="100%" height="100%">
<style>
image {
transform-box: fill-box;
}
</style>
<image x="100" y="100" width="50" href="..."></image>
... other elements
</svg>
That changes the transfom co-ordinate system from the default viewBox (view-box as a CSS value) to the bounding box of the image which would appear to be what you want. Once you do that, translate percentages will work as you wish them to.
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
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