Create curved background with box-shadow [duplicate] - html

I am thinking how to style a squizzed box like this:
I found that I can achieve a similar result with pseudo elements and border-radius as percentage.
Here is the CodePen: https://codepen.io/micu22/pen/eYzpmqR
And here is the code:
div {
background: lightblue;
padding: 10px 20px;
border-radius: 8px;
position: relative;
}
div::after,
div::before {
content: "";
position: absolute;
background: white;
width: 100%;
height: 20px;
left: 0;
}
div::before {
top: -17px;
border-radius: 50%;
}
div::after {
bottom: -17px;
border-radius: 50%;
}
But maybe there is an easier or just more elegant solution?

I would do it like below, using gradient coloration and an SVG filter:
.box {
width:200px;
height:250px;
background:
/* v-- adjust the 15% here */
radial-gradient(50% 15% at top, transparent 98.5%,lightblue) top,
radial-gradient(50% 15% at bottom,transparent 98.5%,lightblue) bottom;
background-size:100% 51%;
background-repeat:no-repeat;
filter: url('#goo');
}
<div class="box"></div>
<svg style="visibility: hidden; position: absolute;" width="0" height="0" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs> <!-- adjust the the 13 here --v -->
<filter id="goo"><feGaussianBlur in="SourceGraphic" stdDeviation="13" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
</defs>
</svg>

It depends on how the content is going to exist. If this is a fixed height container, I'd probably opt for a solution using an SVG background.
I think the most elegant (or at least intrinsic) solution would involve using clipping paths. This would allow you to create an SVG of the exact shape you want and clip the container or background image for the container so that you aren't disguising a still technically visible part of the element.
Clippy is a great tool if you've never worked with clipping masks before.

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">

Placing image inside SVG, removes the SVG

I have this HTML code:
<div class="shape-wave fill-accent">
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 -30 1200 150" preserveAspectRatio="none">
<filter id="dropshadow" y="-100%" height="300%">
<feGaussianBlur in="SourceAlpha" stdDeviation="9"/>
<feOffset dx="0" dy="-2" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="2"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<path class="shape-fill" filter="url(#dropshadow)" d="M985.66,92.83C906.67,72,823.78,31,743.84,14.19c-82.26-17.34-168.06-16.33-250.45.39-57.84,11.73-114,31.07-172,41.86A600.21,600.21,0,0,1,0,27.35V120H1200V95.8C1132.19,118.92,1055.71,111.31,985.66,92.83Z"></path>
</svg>
</div>
and this CSS code:
.shape-wave {
position: absolute;
top: 0;
left: 0;
width: 100%;
overflow: hidden;
line-height: 0;
transform: rotate(180deg);
}
.shape-wave svg {
position: relative;
display: block;
width: calc(100% + 1.3px);
height: 40px;
}
#media (min-width: 720px) {
.shape-wave svg {
height: 70px;
}
}
.fill-accent {
fill: url(/Background.png);
}
When I try to use .fill-accent on the SVG element to fill it with the background image, the SVG completely disappears from the page instead replaced with the below elements background.
what I'm trying to do is have this wave shape filled with the same background image (background.png) as the element above it so it looks like a fluent transition to the next section although I cannot seem to get it to take the image, it works fine when it's just a solid colour.
also sorry I know this is probably a bit of a mess, first time coding HTML really, I'll try to clean it up at the end.

How to use gradient in border in CSS3?

I want the above result, cant use the image because the height of the div is not fixed.
Any help will be appriciated.
You can use pseudo classes & gredient background to creating this. check updated snippet below ...
.msgBox {
padding: 3px;
background: #f9db31;
background: -webkit-linear-gradient(#f9db31 0%, #ff0000 100%);
background: -moz-linear-gradient(#f9db31 0%, #ff0000 100%);
background: -o-linear-gradient(#f9db31 0%, #ff0000 100%);
background: linear-gradient(#f9db31 0%, #ff0000 100%);
float: left;
margin: 50px;
position: relative;
border-radius: 5px;
}
.msgBox::before {
border-bottom: 30px solid transparent;
border-right: 30px solid #f9db31;
border-top: 0 solid transparent;
content: "";
height: 0;
left: -27px;
position: absolute;
top: 25px;
width: 0;
z-index: 999;
}
.msgBox::after {
border-bottom: 28px solid transparent;
border-right: 28px solid #fff;
border-top: 0 solid transparent;
content: "";
height: 0;
left: -21px;
position: absolute;
top: 27px;
width: 0;
z-index: 999;
}
.innerBox {
width: 400px;
min-height: 200px;
background: #fff;
border-radius: 5px;
}
<div class="msgBox">
<div class="innerBox">
</div>
</div>
SVG can be used to create such shapes. It offers simplicity and scale-ability.
However in case your case as you need flexible height element, may
be it doesn't fit your needs. I'm leaving my answer here for a possible alternate for some similar situations where it might be handy.
We can use SVG's path element to create a shape like above and stroke / fill it with some solid color, gradient or a pattern.
Only one attribute d is used to define shapes in path element. This attribute itself contains a number of short commands and few parameters that are necessary for those commands to work.
Following code will create the above shape:
<path d="M0,25 L25,30 V20
Q25,5 40,5 L460,5
Q475,5 475,20 L475,170
Q475,185 460,185 L40,185
Q25,185 25,170 L25,50 Z" />
Below is a brief description of path commands used in above code:
M command is used to define the starting point. It appears at the beginning and specify the point from where drawing should start.
L and V commands are used to draw straight lines.
Q command is used to draw curves.
Z command is used to close current path. It draws a straight line from current point to the starting point to close the shape.
Output Image:
Working Example:
body {
padding: 10px;
}
<svg width="500" height="200" viewBox="0 0 500 200">
<defs>
<linearGradient id="grad" x2="0" y2="1">
<stop offset="0" stop-color="yellow" />
<stop offset="0.5" stop-color="orange" />
<stop offset="1" stop-color="red" />
</linearGradient>
</defs>
<path d="M0,25 L25,30 V20
Q25,5 40,5 L460,5
Q475,5 475,20 L475,170
Q475,185 460,185 L40,185
Q25,185 25,170 L25,50 Z" stroke="url(#grad)" stroke-width="2" fill="none" />
</svg>
Useful Resources:
Below are some useful links for SVG:
Specification
MDN

How to give border radius to make an element look like this image?

I am trying to make .main-div like this image
.main-div {
width: 100px;
height: 100px;
background-color: Red;
border-radius: 30px/20px;
}
<div class="main-div"></div>
My JSFiddle is here.
You can do a trick using a pseudo element and achieve that shape
body {
background: lightgray;
}
.main-div {
position: relative;
display: inline-block;
width: 110px;
height: 100px;
background-color: red;
border-radius: 30%/50%;
background: url(https://i.stack.imgur.com/CWoXa.png) center center no-repeat;
background-size: 110px 110px;
}
.main-div::after {
content: '';
position: absolute;
left: 5px;
top: -5px;
width: 100px;
height: 110px;
background: inherit;
background-size: inherit;
border-radius: 50%/30%;
}
.main-div+.main-div {
background: gray;
}
<div class="main-div"></div>
<div class="main-div"></div>
As Justinas remarked in their answer, the border of your example image does not look like it can be recreated with border-radius alone. This is because the outline is not an ellipse.
It is possible to do this, with good browser support, using SVG as follows.
/* set size of and center SVG */
svg {
display: block;
width: 200px;
height: 200px;
margin: 0 auto;
}
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="outline">
<!-- use Bezier curves to define outline -->
<path d="M 0 100
C 0 0, 40 0, 100 0
C 160 0, 200 0, 200 100
C 200 200, 160 200, 100 200
C 40 200, 0 200, 0 100
Z" />
</clipPath>
</defs>
<image x="0" y="0" width="200" height="200"
xlink:href="https://placehold.it/200"
clip-path="url(#outline)" />
</svg>
This uses clipping in SVG with the clipPath element. You can define any path to use for the clipping. I have used four Bezier curves here. You can tweak where the control points are, or change this to use something entirely different if you wish.
An extra bonus of this approach is that it is now easy to apply other (advanced) filters, for example blurring the image or applying a drop shadow.
/* set size of and center SVG */
svg {
display: block;
width: 204px;
height: 204px;
margin: 0 auto;
}
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="outline">
<!-- use Bezier curves to define outline -->
<path d="M 0 100
C 0 0, 40 0, 100 0
C 160 0, 200 0, 200 100
C 200 200, 160 200, 100 200
C 40 200, 0 200, 0 100
Z" />
</clipPath>
<filter id="dropshadow" x="-30%" y="-30%"
width="160%" height="160%"
color-interpolation-filters="sRGB">
<!-- define color of shadow here -->
<feComponentTransfer in="SourceAlpha">
<feFuncR type="linear" slope="0"
intercept="0.518"></feFuncR>
<feFuncG type="linear" slope="0"
intercept="0.698"></feFuncG>
<feFuncB type="linear" slope="0"
intercept="0.867"></feFuncB>
</feComponentTransfer>
<!-- define blur of shadow here -->
<feGaussianBlur stdDeviation="2" />
<!-- we can offset the shadow -->
<feOffset result="shadow" dx="1" dy="1" />
<!-- put shadow below original content -->
<feBlend in="SourceGraphic"
in2="shadow" mode="normal" />
</filter>
</defs>
<g transform="translate(2, 2)"
filter="url(#dropshadow)">
<image x="0" y="0" width="200" height="200"
xlink:href="https://placehold.it/200"
clip-path="url(#outline)" />
</g>
</svg>
Your image radius does not look like standard CSS border radius. If yes, than you need to use image preprocessing (in back-end side, e.g. GD or stand-alone tool like Photoshop) or use Clipping Mask with limited support. Using border radius you can have similar effect.
.main-div {
width: 100px;
height: 100px;
background-color: red;
border-radius: 40%;
overflow: hidden;
position: relative;
}
.main-div img {
width: 100%;
position: absolute;
left: -50px;
top: -50px;
margin-top: 50%;
margin-left: 50%;
}
<div class="main-div">
<img src="http://lorempixel.com/200/200/"/>
</div>
Add this style. You can change border-radius as per your requirements:
div {
border: 2px solid #a1a1a1;
padding: 10px 15px; `enter code here`
background: #dddddd;
width: 100px;
border-radius: 55px;
}
.element {
border-radius: 50px;
overflow: hidden;
}
<img src="https://image.ibb.co/irvmO5/html5.png" alt="html5" border="0" class="element"><br /><a target='_blank' href='https://imgbb.com/'>Rounded rectangle clip mask</a>

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">