ianpoley
ianpoley

Reputation: 572

Overlapping triangles

Here is the shape I'm trying to create in pure CSS:

CSS overlapping triangles

I have a more complete jsfiddle http://jsfiddle.net/8Lxr5s57/7/. Is there a better, more efficient way to achieve this same result?

.angled_container {
  background-color: #fff;
  height: 200px;
  position: relative;
  overflow: hidden;
  clear: both;
}
.angled_container:before,
.angled_container:after {
  content: "";
  width: 110%;
  height: 100%;
  display: block;
  position: absolute;
  top: 0;
}
.angled_container:before {
  background-color: #606060;
  transform: rotate(12deg);
  -webkit-transform-origin: left top;
  left: 0;
}
.angled_container:after {
  background-color: #6bb2c6;
  transform: rotate(-12deg);
  -webkit-transform-origin: right top;
  left: -10%;
}
.angled_container--open-left:before {
  background-color: #6bb2c6;
  z-index: 2;
}
.angled_container--open-left:after {
  background-color: #606060;
  z-index: 1;
}
<div class="angled_container angled_container--open-right"></div>

Upvotes: 4

Views: 3496

Answers (3)

web-tiki
web-tiki

Reputation: 103760

CSS

I would suggest using skewY() instead of rotate() for the two triangles. it will avoid some positioning issues and prevent using wider pseudo elements than the container :

.angled_container {
  height: 200px;
  position: relative;
  overflow: hidden;
}
.angled_container:before,
.angled_container:after {
  content: "";
  width: 100%; height: 100%;
  display: block;
  position: absolute;
  top: 0; left: 0;
}
.angled_container:before {
  background-color: #606060;
  transform: skewY(12deg);
  transform-origin: left top;
}
.angled_container:after {
  background-color: #6bb2c6;
  transform: skewY(-12deg);
  transform-origin: right top;
}
<div class="angled_container angled_container--open-right"></div>


SVG

Alternatively, you can use an inline SVG with 2 polygon elements. This is totaly responsive and probably easier to make/maintain as you can style the triangles in CSS with the fill property :

svg{display:block; width:100%;}
.first{
  fill:#606060;
}
.second{
  fill:#6bb2c6;
}
<svg viewbox="0 0 100 30">
  <polygon class="first" points="0 0 100 28 0 25 0 28"/>
  <polygon class="second" points="0 28 0 25 100 0 100 28 52 28 50 30 48 28 0"/>
</svg>

Upvotes: 10

Moob
Moob

Reputation: 16184

You can do it all with CSS triangles but I'm not sure its any better than what you have already. You'll need the pseudo elements ::before and ::after to get the extra space at the bottom and the mini arrow.

div {
    width:0;
    height:0;
    margin-top:55px;
    border-top:130px solid white;
    border-right:500px solid #6DB1C3;
    border-bottom:140px solid #6DB1C3;
    border-left:500px solid #5F5F5F;
    position:relative;
}
div:before {
    content:" ";
    position:absolute;
    bottom:-170px;
    width:1000px;
    height:30px;
    left:-500px;
    background:#6DB1C3;
}
div:after {
    content:" ";
    position:absolute;
    bottom:-202px;
    left:-20px;
    width:0;
    height:0;
    border:20px solid transparent;
    border-top:12px solid #6DB1C3;
}
<div></div>

Upvotes: 0

Fionna
Fionna

Reputation: 382

Break them down into triangles. This supports IE8+.

.container {
  position: relative;
  width: 1000px;
  height: 260px;
  border-bottom: 40px solid #65abc2;
}

.grey {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  border-bottom: 260px solid #595959;
  border-right: 1000px solid transparent;
}

.blue {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  border-bottom: 260px solid #65abc2;
  border-left: 1000px solid transparent;
}

.container:after {
  content: '';
  display: block;
  position: absolute;
  bottom: -53px;
  /* included thickness of border-bottom */
  left: 50%;
  margin-left: -17px;
  width: 0px;
  height: 0px;
  border-top: 13px solid #65abc2;
  border-left: 17px solid transparent;
  border-right: 17px solid transparent;
}
<div class="container">
  <div class="grey"></div>
  <div class="blue"></div>
</div>

Upvotes: 0

Related Questions