Theodore K.
Theodore K.

Reputation: 5176

Border-image gradient pattern in triangle shape

I want to create an odd shaped triangle with css. My first thought was to use transparent borders with transform: rotate and it worked (see left triangle). Now I want to use a gradient border image pattern as background for a same triangle but I can't make it work. I tried many things like changing border-width, using wrappers and overflow:hidden among others, nothing worked. Here I post one of my tries (see right shape) as you see the pattern takes all the space, not following the triangle shape. Any ideas?

#top-left {
  position:absolute;
  left:78px;
  width: 0;
  height: 0;
  border-top: 100px solid transparent;  
  border-right: 80px solid black;
  border-bottom: 50px solid transparent;
  -webkit-transform: rotate(-20deg); 
}

#top-right {
  position:absolute;
  left:300px;
  width: 0;
  height: 0;
  border-image: repeating-linear-gradient( 0deg, pink, pink 1%, purple 1%, purple 8%) 10;
  border-image-width: 100px 80px 50px 0px;
  border-width: 100px 80px 50px 0px;
  border-style: solid;
  -webkit-transform: rotate(-20deg); 
}
<div id="wrapper">
 <div id="top-left"></div>  
 <div id="top-right"></div>
</div>

Edit: Andrey Fedorov's answer is good, but there is a problem when the background is not a solid color, like this for example:

body{  
background-color: #6d695c;
background-image:
repeating-linear-gradient(120deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 1px, transparent 1px, transparent 60px),
repeating-linear-gradient(60deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 1px, transparent 1px, transparent 60px),
linear-gradient(60deg, rgba(0,0,0,.1) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.1) 75%, rgba(0,0,0,.1)),
linear-gradient(120deg, rgba(0,0,0,.1) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.1) 75%, rgba(0,0,0,.1));
background-size: 70px 120px;
}
#wrapper {
  position: relative;
}

#top-left {
  position:absolute;
  left:0px;
	width: 0;
	height: 0;
	border-top: 100px solid #fff;  
	border-right: 80px solid transparent;
	border-bottom: 50px solid #fff;
  -webkit-transform: rotate(-20deg); 
}

#top-right {
  position:absolute;
  z-index: -10;
  left:0;
  width: 0;
  height: 0;
  border-image: repeating-linear-gradient( 0deg, pink, pink 1%, purple 1%, purple 8%) 10;
  border-image-width: 100px 80px 50px 0px;
  border-width: 100px 80px 50px 0px;
  border-style: solid;
  -webkit-transform: rotate(-20deg); 
}
<div id="wrapper">
 <div id="top-left"></div>  
 <div id="top-right"></div>
</div>

Upvotes: 2

Views: 1154

Answers (2)

G-Cyrillus
G-Cyrillus

Reputation: 106068

You still can use linear-gradient with no-repeat and background-size to draw each pieces :

examples by steps from a single tag :

/* testing gradients */
p , div#wrapper {
  width:80px;
  float:left;
  margin:1em;
  height:150px;
  /* see me then remove this  shadow */
  box-shadow:0 0 0 2px;
}
p {
  background:
    linear-gradient(130deg, transparent 49.75%, pink 50.5%) 0 42px  no-repeat ;
  background-size:
    100% 15px;
  transform: rotate(-20deg); 
}
p + p{
  background:
    linear-gradient(130deg, transparent 49.75%, pink 50.5%) 0 42px  no-repeat ,
    linear-gradient(130deg,transparent 62px, purple 63px) top no-repeat;
  background-size:
    100% 15px,
    100% 65%;
}
p + p + p {
  
  background:
    linear-gradient(130deg, transparent 49.75%, pink 50.5%) 0 42px  no-repeat ,
    linear-gradient(130deg,transparent 62px, purple 63px) top no-repeat,
    linear-gradient(33deg , transparent 42px, pink 43px) no-repeat bottom;
  background-size:
    100% 15px,
    100% 65%, 
    100% 8px;
}
p+ p + p + p {
    background:
    linear-gradient(130deg, transparent 49.75%, pink 50.5%) 0 42px  no-repeat ,
    linear-gradient(130deg,transparent 62px, purple 63px) top no-repeat,
    linear-gradient(33deg , transparent 42px, pink 43px) no-repeat bottom, 
    linear-gradient(33deg, transparent 42px, purple 43px) bottom no-repeat;
  background-size:
    100% 15px,
    100% 65%, 
    100% 8px, 
    100% 35.5%;
  }
p:last-of-type{
  box-shadow:0 0
}

/* your original CSS/issue */
body{  
background-color: #6d695c;
background-image:
repeating-linear-gradient(120deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 1px, transparent 1px, transparent 60px),
repeating-linear-gradient(60deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 1px, transparent 1px, transparent 60px),
linear-gradient(60deg, rgba(0,0,0,.1) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.1) 75%, rgba(0,0,0,.1)),
linear-gradient(120deg, rgba(0,0,0,.1) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.1) 75%, rgba(0,0,0,.1));
background-size: 70px 120px;
}
#wrapper {
  position: relative;
}

#top-left {
  position:absolute;
  left:0px;
	width: 0;
	height: 0;
	border-top: 100px solid #fff;  
	border-right: 80px solid transparent;
	border-bottom: 50px solid #fff;
  -webkit-transform: rotate(-20deg); 
  transform: rotate(-20deg); 
}

#top-right {
  position:absolute;
  z-index: -10;
  left:0;
  width: 0;
  height: 0;
  border-image: repeating-linear-gradient( 0deg, pink, pink 1%, purple 1%, purple 8%) 10;
  border-image-width: 100px 80px 50px 0px;
  border-width: 100px 80px 50px 0px;
  border-style: solid;
  -webkit-transform: rotate(-20deg); 
  transform: rotate(-20deg); 
}
<!-- your issue -->
<div id="wrapper">
 <div id="top-left"></div>  
 <div id="top-right"></div>
</div>
<!-- p for testing purpose -->
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>

inbricated element + gradient & transform could do too:

body{  
background-color: #6d695c;
background-image:
repeating-linear-gradient(120deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 1px, transparent 1px, transparent 60px),
repeating-linear-gradient(60deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 1px, transparent 1px, transparent 60px),
linear-gradient(60deg, rgba(0,0,0,.1) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.1) 75%, rgba(0,0,0,.1)),
linear-gradient(120deg, rgba(0,0,0,.1) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.1) 75%, rgba(0,0,0,.1));
background-size: 70px 120px;
}

div.inbricate {
  margin:1em;
  height:150px;
  width:80px;
  position:relative;
  overflow:hidden;
  transform:rotate(-20deg);
  box-shadow: 0 0 ;
}
.inbricate div {
  transform:rotate(31deg) scale(1.2, 0.9) skew(-5deg);
  transform-origin: 100% 102%;
  height:100%;
  background:linear-gradient(-40deg,   pink 8%, purple 8%, purple 65%, pink 65%, pink 75%, purple 75% )
}
<div class=inbricate>
  <div>
  </div>
</div>

Upvotes: 1

Andrei Fedorov
Andrei Fedorov

Reputation: 3997

One possible solution is this:

  • Put both shapes in the same place.
  • Using z-index make the one with the pattern go behind the other
  • Use white (or whatever color is the shape background) to paint the border area outside the triangle.
  • Make transparent the border that had the triangle color

#wrapper {
  position: relative;
  }

#top-left {
  position:absolute;
  left:0px;
	width: 0;
	height: 0;
	border-top: 100px solid #fff;  
	border-right: 80px solid transparent;
	border-bottom: 50px solid #fff;
  -webkit-transform: rotate(-20deg); 
}

#top-right {
  position:absolute;
  z-index: -10;
  left:0;
  width: 0;
  height: 0;
  border-image: repeating-linear-gradient( 0deg, pink, pink 1%, purple 1%, purple 8%) 10;
  border-image-width: 100px 80px 50px 0px;
  border-width: 100px 80px 50px 0px;
  border-style: solid;
  -webkit-transform: rotate(-20deg); 
}
<div id="wrapper">
 <div id="top-left"></div>  
 <div id="top-right"></div>
</div>

Upvotes: 1

Related Questions