22

I have a shape with an edge like this in Photoshop:

image

Is it possible to make the repeated triangles as a border with CSS?

web-tiki
  • 99,765
  • 32
  • 217
  • 249
svbnet
  • 1,070
  • 3
  • 11
  • 29
  • 1
    For a similar effect with curved bottom edges (like droplets) instead of triangular ones, refer [this answer](http://stackoverflow.com/questions/25895895/creating-a-droplet-like-border-effect-in-css/25903879#25903879). – Harry May 17 '15 at 13:38
  • Not responsive but a solution for this can be found on http://css-shapes.xyz/saw-tooth-border-effect – Akshay Oct 16 '15 at 15:24

5 Answers5

40

You can use gradients to create a zig-zag patterned background, use the ::after pseud-element to apply it like a border.

.header{
    color: white;
    background-color: #2B3A48;
    text-align: center;
}
.header::after {
    content: " ";
    display: block;
    position: relative;
    top: 0px;
    left: 0px;
    width: 100%;
    height: 36px;
    background: linear-gradient(#2B3A48 0%, transparent 0%), linear-gradient(135deg, #272220 33.33%, transparent 33.33%) 0 0%, #272220 linear-gradient(45deg, #272220 33.33%, #2B3A48 33.33%) 0 0%;
    background-repeat: repeat-x;
    background-size: 0px 100%, 9px 27px, 9px 27px;
}
<div class="header"><h1>This is a header</h1></div>

Source: CSS Zigzag Border with a Textured Background

JSFiddle: http://jsfiddle.net/kA4zK/

TylerH
  • 20,799
  • 66
  • 75
  • 101
extramaster
  • 2,635
  • 2
  • 23
  • 28
18

For future viewers, I found this adaptation of @extramaster's answer to be a little simpler.

It's essentially the same, but it uses one fewer background gradients and allows the backing object (.navbar in my markup) to show through instead of hard-coding the second color into the zig-zag.

JsFiddle: http://jsfiddle.net/861gjx0b/2/

.header {
  position: relative;
  color: white;
  background-color: #2B3A48;
  text-align: center;
}

.navbar {
  background: #272220;
  height: 20px;
}

.header:after {
  content: "";
  position: absolute;
  display: block;
  height: 10px;
  bottom: -10px;
  /* -height */
  left: 0;
  right: 0;
  /* TODO Add browser prefixes */
  background: linear-gradient( 45deg, transparent 33.333%, #2B3A48 33.333%, #2B3A48 66.667%, transparent 66.667%), linear-gradient( -45deg, transparent 33.333%, #2B3A48 33.333%, #2B3A48 66.667%, transparent 66.667%);
  background-size: 8px 20px;
  /* toothSize doubleHeight */
  background-position: 0 -10px;
  /* horizontalOffset -height */
}
<div class="header">
  <h1>This is a header</h1>
</div>
<nav class="navbar"></nav>
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63
mxdubois
  • 605
  • 8
  • 14
10

Personally, I think clip-path is easier to work with/understand than complex background gradients.

body {
  font-family:Roboto,'Open Sans',Helvetica,sans-serif;
}
.container {
  background:#ddd;
  margin:0 auto; 
  max-width:800px;
  padding:30px;
}
h1:first-child {margin:0;}

.jagged-bottom {
  position:relative;
}
.jagged-bottom:after {
  background:#ddd;
  content:"";
  height:2vw;
  position:absolute;
  top:100%;
  left:0;
  right:0;
  clip-path:polygon(
     0 0, 2.5% 100%, 5% 0,  7.5% 100%, 
   10% 0,12.5% 100%,15% 0, 17.5% 100%, 
   20% 0,22.5% 100%,25% 0, 27.5% 100%, 
   30% 0,32.5% 100%,35% 0, 37.5% 100%, 
   40% 0,42.5% 100%,45% 0, 47.5% 100%, 
   50% 0,52.5% 100%,55% 0, 57.5% 100%, 
   60% 0,62.5% 100%,65% 0, 67.5% 100%, 
   70% 0,72.5% 100%,75% 0, 77.5% 100%, 
   80% 0,82.5% 100%,85% 0, 87.5% 100%, 
   90% 0,92.5% 100%,95% 0, 97.5% 100%, 100% 0);
}
<div class="container jagged-bottom">
  <h1>Looks Like A Receipt</h1>
  <p>Simply adjust the clip path on the pseudo-element if you want more or fewer spikes, and the height if you want them to be taller or shorter.</p>
</div>
Walk
  • 737
  • 4
  • 15
Daniel Fowler
  • 385
  • 7
  • 21
  • Here's a Python3 incantation that might come in handy if you need a different `clip-path`. Be sure to change the 2.5 and 41 magic numbers if you needed more or less teeth: ', '.join(list(map(lambda x: f"{x[1]}% {'100%' if (x[0]%2==1) else '0'}", enumerate([x * 2.5 for x in range(0, 41)])))) – Marcus Junius Brutus Jan 26 '23 at 17:15
1

There is a border-image property in CSS3. Maybe you can work it out in a way you want. More here:

https://developer.mozilla.org/en-US/docs/Web/CSS/border-image

Or here

https://www.w3schools.com/cssref/css3_pr_border-image.asp

TylerH
  • 20,799
  • 66
  • 75
  • 101
marinbgd
  • 739
  • 13
  • 28
0

You can create an individual triangle using CSS quite easily (just tweak border properties). In order for this to work you will need to generate quite a bit of markup yourself. I would recommend against this approach.

Instead you are likely better off using an individual image containing a single triangle (preferably a transparent .png) and then use background-image and background-repeat (repeat-x) properties to bind that to a div (your "border").

Unfortunately there is no yet a straight-forward way to achieve this using pure CSS.

Juho Vepsäläinen
  • 26,573
  • 12
  • 79
  • 105