using svg line to imitate border of div - html

The end goal of this
use svg line to underscore border of div that contains it
webkit animation effects dash forwards to imitate border effects
If possible, the line to "be" the top border of the div
The problem is the extra padding below the top of the containing div. I do not know the source of the padding. Any tries at top: 0; or margin: 0; are unsuccessful.
Actual Results
The line is affected by unknown padding and pushed down a bit
I have an svg line with a div that contains it. This all happens in the ...
HTML
<div style = "display: inline;" id="divDisplay">
<svg height="1" width="1500">
<line id="top" x1="0" y1="0" x2="1500" y2="0" />
</svg>
</div>
CSS
#divDisplay {
background:linear-gradient(to bottom, #8dd2d9 , #58c0c7);
border: 2px solid #dadada;
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #111;
height: 100px;
}
#top {
top: 0;
position: fixed;
margin:0;
stroke: rgb(112,111,111);
stroke-width: 5;
stroke-dasharray:1300;
stroke-dashoffset:1300;
-webkit-animation: dash-top 3.00s forwards;
}
#-webkit-keyframes dash-top {
to { stroke-dashoffset: 0; }
}

This is because the <svg> element is inline by default, so vertical-align applies and defaults to baseline.
A quick fix is to change the vertical-align value: updated fiddle
svg {
vertical-align: top;
}

Not sure about the root cause, but adding the following css solved it.
#divDisplay svg
{
position:absolute;
top:1;
}
http://jsfiddle.net/wmeLa8tc/

Related

How to implement a repeating SVG at the top and bottom of a div? [duplicate]

I've been working on a header with a zigzag border. One way to do this is to use images to make the zigzag effect.
(1) Is there any way to create a practical cross-browser zigzag border in CSS without the use of images?
I am also trying to put a textured background on this header that extends to the zigzags. However, the vertical size of the header may change and I am unable to implement the header as a single image.
If I try to add a texture to both the zigzag edges and the header element, chances are, the texture will be off sync.
(2) Any ideas on implementing a textured background that extends onto the zigzags without being off sync?
My [old] code (along with a texture) is here on jsFiddle.
body {
padding: 20px;
}
header {
width: 240px;
background-color: #BCED91;
}
header:after {
content: " ";
display: block;
position: relative;
width: 240px;
bottom: -15px;
height: 15px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAPCAYAAACWV43jAAAAw0lEQVRIx83RsQ3CMBCF4T83AZKLVOmyBa1HSIlXwKySGaDOBClZAToWQIpETQONyxAS+2J4pe9knd5X9EP7QicPYAsUwBnYaHwqSsd1QGmNv1rjL0AZ3pJTKDTorPGnsUE/tDvg+KsG70D96TiAMKvDbtYDO6Cyxt++LYadKpY8hthNtTaVGHLRJJ3R5mJy0SbVJp9D7FJaSyWXNUk1yGVt0lTyMWK3ZmtLySUnaQy55CZdSi7AHmis8U/+JOGWBji8AaYPVy6VELZvAAAAAElFTkSuQmCC) repeat-x;
}
img {
margin-top: 50px;
}
<header>
<br />
<br />
<br />
<br />
</header>
<img src="http://i.imgur.com/qKsVr.png" />
Edit #1:
Thank you Ana for the code. I took it and improved upon it.
http://dabblet.com/gist/3401493
I don't think that a consistent background will be possible.
If you are going to use border-image, then it's not a cross-browser solution because IE doesn't support it.
Also, even though every current browser version except IE9 supports both CSS gradients (which would allow you to get a zig-zag pattern) and border-image, last time I checked (which was quite a few months ago, so better test this again), using gradients for border-image only worked in WebKit. Plus, I don't think that even in WebKit this works with more than one gradient (as you can only set one border image and one gradient is one image) and you need two gradients for the zig-zag pattern.
The code for the CSS zig-zag pattern is:
background: linear-gradient(#BCED91 49%, transparent 49%),
linear-gradient(-45deg, white 33%, transparent 33%) 0 50%,
white linear-gradient(45deg, white 33%, #BCED91 33%) 0 50%;
background-repeat: repeat-x;
background-size: 1px 100%, 40px 40px, 40px 40px;
If you want a texture below this that is in sync with this one, then you have to make sure it repeats at the same intervals (40px, but you could also go for 20px).
Edit: regarding polyfills, you could try one of the ones listed here: CSS3 PIE or cssSandpaper
(In modern browsers) you can use SVGs to create simple drawings, and use them as CSS background images embedded as data URI.
Here is what the SVGs look like:
body {
background: #888;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
<polygon points="0,4 4,0 8,4" fill="#CC0000" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
<polygon points="0,0 4,4 8,0" fill="#CC0000" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
<polygon points="0,0 4,4 8,0" fill="#FFFFFF" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
<polygon points="0,4 4,0 8,4" fill="#FFFFFF" />
</svg>
Example 1:
.zigzag-outside {
position: relative;
margin-top: 4px;
margin-bottom: 4px;
background-color: #CC0000;
/* example content */
padding: 1em;
font: bold medium sans-serif;
color: #FFFFFF;
}
.zigzag-outside:before {
content: "";
position: absolute;
top: -4px;
left: 0;
right: 0;
height: 4px;
/* red up pointing triangle */
background-image: url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228px%22%20height%3D%224px%22%3E%3Cpolygon%20points%3D%220%2C4%204%2C0%208%2C4%22%20fill%3D%22%23CC0000%22%2F%3E%3C%2Fsvg%3E");
}
.zigzag-outside:after {
content: "";
position: absolute;
bottom: -4px;
left: 0;
right: 0;
height: 4px;
/* red down pointing triangle */
background-image: url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228px%22%20height%3D%224px%22%3E%3Cpolygon%20points%3D%220%2C0%204%2C4%208%2C0%22%20fill%3D%22%23CC0000%22%2F%3E%3C%2Fsvg%3E");
}
<div class="zigzag-outside">Example 1</div>
Example 2:
.zigzag-inside {
position: relative;
/* example content */
width: 600px;
height: 100px;
background-image: url(http://i.stack.imgur.com/uOVfl.jpg);
}
.zigzag-inside:before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
/* white down pointing triangle */
background-image: url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228px%22%20height%3D%224px%22%3E%3Cpolygon%20points%3D%220%2C0%204%2C4%208%2C0%22%20fill%3D%22%23FFFFFF%22%2F%3E%3C%2Fsvg%3E");
}
.zigzag-inside:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 4px;
/* white up pointing triangle */
background-image: url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228px%22%20height%3D%224px%22%3E%3Cpolygon%20points%3D%220%2C4%204%2C0%208%2C4%22%20fill%3D%22%23FFFFFF%22%2F%3E%3C%2Fsvg%3E");
}
<div class="zigzag-inside"></div>
Improved minimal CSS:
div {
background: #1ba1e2;
position: relative;
}
div:after {
content: "";
display: block;
position: absolute;
width: 100%;
height: 30px;
background: linear-gradient(-45deg, transparent 75%, #1ba1e2 0) 0 50%,
linear-gradient(45deg, transparent 75%, #1ba1e2 0) 0 50%;
background-size: 30px 30px;
}
/* Styles just for demo */
h1 {
color: #fff;
text-align: center;
margin: 0;
padding: 0.5em;
}
<div>
<h1>Zig Zag Borders</h1>
</div>
If you want to remove duplicate values you can use CSS variables AKA Custom properties. They are working everywhere except IE.
:root {
--background-color: #1ba1e2;
--zigzag-item-size: 30px;
}
div {
background: var(--background-color);
position: relative;
}
div:after {
content: "";
display: block;
position: absolute;
width: 100%;
height: var(--zigzag-item-size);
background: linear-gradient(-45deg, transparent 75%, var(--background-color) 0) 0 50%,
linear-gradient(45deg, transparent 75%, var(--background-color) 0) 0 50%;
background-size: var(--zigzag-item-size) var(--zigzag-item-size);
}
/* Styles just for demo */
h1 {
color: #fff;
text-align: center;
margin: 0;
padding: 0.5em;
}
<div>
<h1>Zig Zag Borders</h1>
</div>
Small note:
I use zero 0 in gradient color-stops to avoid duplicating previous values because according to the CSS3 images specs color-stop position can't be less than previous one.
If a color-stop has a position that is less than the specified position of any color-stop before it in the list, set its position to be equal to the largest specified position of any color-stop before it.
Now using mask and one gradient you can do it. Check this online generator to get the code: https://css-generators.com/custom-borders/. You can find all the directions and combination of Zig-Zag
body {
padding: 20px;
}
header {
min-height: 200px;
background-color: #BCED91;
}
img {
margin-top: 50px;
}
.zig-zag {
--mask: conic-gradient(from -45deg at bottom,#0000,#000 1deg 90deg,#0000 91deg) 50% / 60px 100%;
-webkit-mask: var(--mask);
mask: var(--mask);
}
<header class="zig-zag">
</header>
<img src="http://i.imgur.com/qKsVr.png" class="zig-zag">

CSS - Animate object in curved path

I just want to animate my image through curved path. Like this way. ( I'm using position absolute for positioning. ) Did some research and found that css transform can do the job. It can be easily done by straight line. But curved path?
I tried to combine with css transform-origin + transform:rotate but I didn't get exact that I want. Clearly I want to move around 80% to the left curved and need to come to original position. I tried so many times adjusting my code but still no luck.
Fiddle
P.S
What is transform-origin really do here? Is it necessary?
Can someone explain me about how transform:rotate works here?
Here is my code
.sun{
width: 5.7%;
position: absolute;
top: -5%;
left: 57%;
animation: circle 10s linear infinite;
transform-origin: 0px 700px;
animation-fill-mode: forwards;
animation-direction: alternate;
}
#keyframes circle {
from {
transform:rotate(-60deg);
}
to {
transform:rotate(40deg);
}
}
<div class="sun">
<img src="sun.png" alt="">
</div>
Maybe make parent element move by rotate and children (in my case pseudoelement, whatever) make position absolute to the parent. And just use animation. Look at my solution. Maybe you will have to create some wrapper and use overflow: hidden, because it is square which is rotating. You can watch square's behavior by adding background-color.
#keyframes move-sun {
from {
transform: rotate(0deg);
}
to {
transform: rotate(90deg);
}
}
.sun {
position: relative;
width: 400px;
height: 400px;
margin: 200px;
transform: rotate(90deg);
animation: move-sun 10s;
}
.sun::before {
content: "";
position: absolute;
top: -25px;
left: -25px;
width: 50px;
height: 50px;
background-color: #ff0;
border-radius: 50%;
}
<div class="sun">
</div>
I realize this is an old question, but I just wanted to add another option. You could use 2 separate animations, one for the x-motion and one for the y-motion:
body {
background: #8DBECC;
}
.container {
position: relative;
height: 100%;
width: 100%;
}
.sun {
position: absolute;
width: 30px;
height: 200px;
animation: x-motion 3s ease-in-out 0s infinite alternate;
}
.sun:before {
content: '';
width: 30px;
height: 30px;
position: absolute;
top: 100%;
background: #F18C3E;
animation: y-motion 3s ease-in-out 0s infinite alternate;
border-radius: 15px;
}
#keyframes x-motion {
0% {
left: 0;
}
100% {
left: calc(100% - 30px);
}
}
#keyframes y-motion {
0%, 100% {
top: 100%;
}
50% {
top: 0%;
}
}
<html>
<body>
<div class="container">
<div class="sun">
</div>
</div>
</body>
</html>
https://jsfiddle.net/561pbt0r/27/
It might not be easy with CSS, but you can easily do this with SVG animation.
I modified a sample from this tutorial for your case:
<svg width="500" height="350" viewBox="0 0 350 350">
<path id="motionPath" fill="none" stroke="#000000" stroke-miterlimit="10" d="M100,100Q250,-50,400,100"/>
<g id="sun" transform="translate(-100, -300)">
<circle cx="100" cy="300" r="25" fill="yellow"/>
</g>
<animateMotion
xlink:href="#sun"
dur="3s"
begin="0s"
fill="freeze"
repeatCount="indefinite"
>
<mpath xlink:href="#motionPath" />
</animateMotion>
</svg>
When you want to apply some transform operation to an element, that transformation has a reference point from where it will be applied. That is the origin point and by default it is at the center of every element (i.e.: transform-origin(50% 50%)).
With this statement you can modify that origin whenever you need the transformation to apply from a different origin.
Here you can see an example when the rotation is done from the top left corner. Without the origin modification, it would rotate around its center.
Note: You can set the transform-origin even outside the element

Creating a skewed triangle shape

Is it possible to create the shape produced by this Fiddle. But then with no JavaScript but CSS3 (with <div>) ?
Basically this:
for(var i = 0; i < coords.length; i += 1) {
if(coords[(i + 1)] != undefined) {
ctx.beginPath();
ctx.moveTo(coords[i].x, coords[i].y);
ctx.lineTo(coords[(i + 1)].x, coords[(i + 1)].y);
ctx.stroke();
} else {
ctx.beginPath();
ctx.moveTo(coords[i].x, coords[i].y);
ctx.lineTo(coords[0].x, coords[0].y);
ctx.stroke();
}
}
So you have points that needs to connect to each other?
Use svg, if you don't want to use canvas.
<svg width="100" height="100">
<path d="M0 0 l100 10 l-40 90z" fill="none" stroke="black" stroke-width="2" />
</svg>
Path command for 8,8,10,10,30,30,49,10 would be M8 8 L10 10 L30 40 L49 10z.
<svg width="49" height="40" viewBox="0 0 50 41">
<path d="M8 8 L10 10 L30 40 L49 10z" fill="none" stroke="black" stroke-width="2" />
</svg>
To apply a click event to the shape, you could use pointer-events: all on #test.
#test {
pointer-events: all;
}
<svg width="49" height="40" viewBox="0 0 50 41">
<path id="test" d="M8 8 L10 10 L30 40 L49 10z" fill="none" onclick="alert('Works')" stroke="black" stroke-width="2" />
</svg>
Note: Posting this answer just because you asked with CSS3, but the complexity and possible calculation overhead involved in this approach is proof enough why CSS shouldn't be used for this. Please do not use this approach.
A bit of explanation on how this was achieved:
A div is created with top and right border (1px black) and the other two borders are set to none.
This div is then skewed a bit to make it appear as though the edge on the right side is a bit slanted.
Inside the shape, a pseudo-element with only a right border is created and it is also skewed to produce the diagonal line from the right-bottom to the left-top. Transform origin is set as right-bottom to avoid positioning overhead.
An anchor tag is added within the parent div and the overflow is set to hidden so that only the portion within the shape is clickable.
The user select on the anchor tag are disabled to prevent a double click from selecting a blank space within the div.
Finally the whole container div is rotated a bit to make it look as though the triangle is not parallel to x-axis.
document.getElementById("clickme").onclick = function() {
alert('Hi! I work alright.');
}
div {
position: relative;
height: 50px;
width: 45px;
border: 1px solid black;
border-left: none;
border-bottom: none;
-webkit-transform: skew(-10deg) rotate(5deg);
-moz-transform: skew(-10deg) rotate(5deg);
transform: skew(-10deg) rotate(5deg);
overflow: hidden;
}
a {
display: block;
content: '';
margin-left: 0px;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
height: 100%;
width: 100%;
}
div:after {
position: absolute;
top: 0px;
left: 0px;
content: '';
height: 50px;
width: 45px;
-webkit-transform: skew(42deg);
-webkit-transform-origin: left bottom;
-moz-transform: skew(42deg);
-moz-transform-origin: left bottom;
transform: skew(42deg);
transform-origin: left bottom;
border-right: 1px solid black;
}
<div>
</div>
Another option to create a skewed triangle shape would be to use clip-path like in below snippet. The shape is created by applying the same clip-path on the main container element and a pseudo-element which is smaller than the container.
document.getElementById("clickme").onclick = function() {
alert('Hi! I work alright.');
}
div {
position: relative;
height: 150px;
width: 150px;
background: black;
-webkit-clip-path: polygon(0% 0%, 100% 20%, 70% 100%);
}
div:after{
position: absolute;
content: '';
height: calc(100% - 5px);
width: calc(100% - 5px);
top: 2px;
left: 3px;
background: white;
-webkit-clip-path: polygon(0% 0%, 100% 20%, 70% 100%);
}
/* Just for demo */
div{
transition: all 1s;
}
div:hover{
height: 250px;
width: 250px;
}
<div id="clickme"></div>
You can do it by embeding SVG as CSS. Quote from:
http://css-tricks.com/using-svg/
"Another way to use SVG's is to convert them into Data URI's. Data URI's might not save you actual file size, but can be more efficient because the data is right there. It doesn't require an additional HTTPRequest.
Mobilefish.com has an online conversion tool for that (http://www.mobilefish.com/services/base64/base64.php). Simply paste in the contents of your SVG file and fill out the form and it will display the results in a textarea for you to copy. Remember to remove line breaks in the data it gives you back.
...
You can use that anywhere we've talked about so far (except inline because that just doesn't make sense) Just put the gibberish where it says [data] in these examples.
As CSS
.logo {
background: url(data:image/svg+xml;base64,[data]);
}
"

SVG coordinates shifted

I'm trying to fit an svg into a div. The svg contains of a single path. I've set up viewBox and preserveAspectRatio correctly, I think, but a part of the path (which is supposed to fit entirely in the svg) is drawn outside the viewBox. Here's the fiddle, and here's the code:
html:
<div class='sparkline' class="ng-isolate-scope">
<svg viewBox="1 1 10 10" preserveAspectRatio="none">
<path d="M0,10L5,5L10,0"></path>
</svg>
</div>
css:
path {
stroke: blue;
stroke-width: 0.2;
fill: none;
}
.sparkline{
width: 200px;
height: 200px;
position:absolute;
top:0px;
left:0px;
border: 1px solid black;
margin: 20px;
}
svg{
width:100%;
height:100%;
display: block;
position: absolute;
top: 0px;
left: 0px;
}
I see no reason for the line to be shifted to the left, how can I overcome this?
Your code works as expected, but it possibly contains a typo. Provided that the viewBox is defined between 1 and 10, the line with 0 in X or/and Y should look shifted off the box.
Use viewBox="0 0 10 10" to fit the line into diagonal of the box.

CSS Zigzag Border with a Textured Background

I've been working on a header with a zigzag border. One way to do this is to use images to make the zigzag effect.
(1) Is there any way to create a practical cross-browser zigzag border in CSS without the use of images?
I am also trying to put a textured background on this header that extends to the zigzags. However, the vertical size of the header may change and I am unable to implement the header as a single image.
If I try to add a texture to both the zigzag edges and the header element, chances are, the texture will be off sync.
(2) Any ideas on implementing a textured background that extends onto the zigzags without being off sync?
My [old] code (along with a texture) is here on jsFiddle.
body {
padding: 20px;
}
header {
width: 240px;
background-color: #BCED91;
}
header:after {
content: " ";
display: block;
position: relative;
width: 240px;
bottom: -15px;
height: 15px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAPCAYAAACWV43jAAAAw0lEQVRIx83RsQ3CMBCF4T83AZKLVOmyBa1HSIlXwKySGaDOBClZAToWQIpETQONyxAS+2J4pe9knd5X9EP7QicPYAsUwBnYaHwqSsd1QGmNv1rjL0AZ3pJTKDTorPGnsUE/tDvg+KsG70D96TiAMKvDbtYDO6Cyxt++LYadKpY8hthNtTaVGHLRJJ3R5mJy0SbVJp9D7FJaSyWXNUk1yGVt0lTyMWK3ZmtLySUnaQy55CZdSi7AHmis8U/+JOGWBji8AaYPVy6VELZvAAAAAElFTkSuQmCC) repeat-x;
}
img {
margin-top: 50px;
}
<header>
<br />
<br />
<br />
<br />
</header>
<img src="http://i.imgur.com/qKsVr.png" />
Edit #1:
Thank you Ana for the code. I took it and improved upon it.
http://dabblet.com/gist/3401493
I don't think that a consistent background will be possible.
If you are going to use border-image, then it's not a cross-browser solution because IE doesn't support it.
Also, even though every current browser version except IE9 supports both CSS gradients (which would allow you to get a zig-zag pattern) and border-image, last time I checked (which was quite a few months ago, so better test this again), using gradients for border-image only worked in WebKit. Plus, I don't think that even in WebKit this works with more than one gradient (as you can only set one border image and one gradient is one image) and you need two gradients for the zig-zag pattern.
The code for the CSS zig-zag pattern is:
background: linear-gradient(#BCED91 49%, transparent 49%),
linear-gradient(-45deg, white 33%, transparent 33%) 0 50%,
white linear-gradient(45deg, white 33%, #BCED91 33%) 0 50%;
background-repeat: repeat-x;
background-size: 1px 100%, 40px 40px, 40px 40px;
If you want a texture below this that is in sync with this one, then you have to make sure it repeats at the same intervals (40px, but you could also go for 20px).
Edit: regarding polyfills, you could try one of the ones listed here: CSS3 PIE or cssSandpaper
(In modern browsers) you can use SVGs to create simple drawings, and use them as CSS background images embedded as data URI.
Here is what the SVGs look like:
body {
background: #888;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
<polygon points="0,4 4,0 8,4" fill="#CC0000" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
<polygon points="0,0 4,4 8,0" fill="#CC0000" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
<polygon points="0,0 4,4 8,0" fill="#FFFFFF" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="8px" height="4px">
<polygon points="0,4 4,0 8,4" fill="#FFFFFF" />
</svg>
Example 1:
.zigzag-outside {
position: relative;
margin-top: 4px;
margin-bottom: 4px;
background-color: #CC0000;
/* example content */
padding: 1em;
font: bold medium sans-serif;
color: #FFFFFF;
}
.zigzag-outside:before {
content: "";
position: absolute;
top: -4px;
left: 0;
right: 0;
height: 4px;
/* red up pointing triangle */
background-image: url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228px%22%20height%3D%224px%22%3E%3Cpolygon%20points%3D%220%2C4%204%2C0%208%2C4%22%20fill%3D%22%23CC0000%22%2F%3E%3C%2Fsvg%3E");
}
.zigzag-outside:after {
content: "";
position: absolute;
bottom: -4px;
left: 0;
right: 0;
height: 4px;
/* red down pointing triangle */
background-image: url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228px%22%20height%3D%224px%22%3E%3Cpolygon%20points%3D%220%2C0%204%2C4%208%2C0%22%20fill%3D%22%23CC0000%22%2F%3E%3C%2Fsvg%3E");
}
<div class="zigzag-outside">Example 1</div>
Example 2:
.zigzag-inside {
position: relative;
/* example content */
width: 600px;
height: 100px;
background-image: url(http://i.stack.imgur.com/uOVfl.jpg);
}
.zigzag-inside:before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
/* white down pointing triangle */
background-image: url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228px%22%20height%3D%224px%22%3E%3Cpolygon%20points%3D%220%2C0%204%2C4%208%2C0%22%20fill%3D%22%23FFFFFF%22%2F%3E%3C%2Fsvg%3E");
}
.zigzag-inside:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 4px;
/* white up pointing triangle */
background-image: url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%228px%22%20height%3D%224px%22%3E%3Cpolygon%20points%3D%220%2C4%204%2C0%208%2C4%22%20fill%3D%22%23FFFFFF%22%2F%3E%3C%2Fsvg%3E");
}
<div class="zigzag-inside"></div>
Improved minimal CSS:
div {
background: #1ba1e2;
position: relative;
}
div:after {
content: "";
display: block;
position: absolute;
width: 100%;
height: 30px;
background: linear-gradient(-45deg, transparent 75%, #1ba1e2 0) 0 50%,
linear-gradient(45deg, transparent 75%, #1ba1e2 0) 0 50%;
background-size: 30px 30px;
}
/* Styles just for demo */
h1 {
color: #fff;
text-align: center;
margin: 0;
padding: 0.5em;
}
<div>
<h1>Zig Zag Borders</h1>
</div>
If you want to remove duplicate values you can use CSS variables AKA Custom properties. They are working everywhere except IE.
:root {
--background-color: #1ba1e2;
--zigzag-item-size: 30px;
}
div {
background: var(--background-color);
position: relative;
}
div:after {
content: "";
display: block;
position: absolute;
width: 100%;
height: var(--zigzag-item-size);
background: linear-gradient(-45deg, transparent 75%, var(--background-color) 0) 0 50%,
linear-gradient(45deg, transparent 75%, var(--background-color) 0) 0 50%;
background-size: var(--zigzag-item-size) var(--zigzag-item-size);
}
/* Styles just for demo */
h1 {
color: #fff;
text-align: center;
margin: 0;
padding: 0.5em;
}
<div>
<h1>Zig Zag Borders</h1>
</div>
Small note:
I use zero 0 in gradient color-stops to avoid duplicating previous values because according to the CSS3 images specs color-stop position can't be less than previous one.
If a color-stop has a position that is less than the specified position of any color-stop before it in the list, set its position to be equal to the largest specified position of any color-stop before it.
Now using mask and one gradient you can do it. Check this online generator to get the code: https://css-generators.com/custom-borders/. You can find all the directions and combination of Zig-Zag
body {
padding: 20px;
}
header {
min-height: 200px;
background-color: #BCED91;
}
img {
margin-top: 50px;
}
.zig-zag {
--mask: conic-gradient(from -45deg at bottom,#0000,#000 1deg 90deg,#0000 91deg) 50% / 60px 100%;
-webkit-mask: var(--mask);
mask: var(--mask);
}
<header class="zig-zag">
</header>
<img src="http://i.imgur.com/qKsVr.png" class="zig-zag">