Search code examples
javascripthtmlcssresponsivediagonal

CSS - How to responsively align diagonal edges?


I am trying to create a responsive diagonal layout (see attached image). Of course, this is a challenge at different screen sizes as the edges come out of alignment (example: see the last two rows on the image).

How can I vertically align the top edge of each slanted shape with the bottom edge of the one above it?

So far, the only way I've found to achieve this is by changing the left position of ::before pseudo element on the skewed shapes. But I would like to achieve this responsively as the size of the rows grow and the screen resizes.

Aligned Edges Example

.slant::before {
  background-color: lightblue;
}

.lr .right-content,
.rr .left-content {
  background-color: green;
}

.lr .slant,
.rr .slant {
  position: relative;
}

.lr .slant::before,
.rr .slant::before {
  content: '';
  transform-origin: 100% 0%;
  position: absolute;
  top: 0;
  bottom: 0;
}

.lr .slant::before {
  transform: skewX(-10deg);
  left: -100vw;
  right: 0;
}

.rr .slant::before {
  transform: skewx(10deg);
  left: 0;
  right: -100vw;
}
<div class="container">
  <div class="row lr one">
    <div class="col-xs-5 left-content slant">
      <h1>Title</h1>
    </div>
    <div class="col-xs-7 right-content">
    </div>
  </div>

  <div class="row rr card two">
    <div class="col-xs-5 left-content">
    </div>
    <div class="col-xs-7 right-content slant">
      <p>Lorem Ipsum is simply dummy...</p>
      <p>Lorem Ipsum is simply dummy...</p>
      <p>Lorem Ipsum is simply dummy...</p>
    </div>
  </div>
  ...
</div>


Solution

  • Here is an idea using clip-path:

    .row {
      position:relative;
      background:lightblue;
      height:50px;
      margin:5px;
    }
    .row::before {
      content:"";
      position:absolute;
      top:0;
      bottom:0;
      width:50%;
      background:green;
    }
    .row.left::before {
      left:0;
      clip-path:polygon(0 0,100% 0, calc(100% - 30px) 100%,0 100%);
    }
    .row.right::before {
      right:0;
      clip-path:polygon(0 0,100% 0, 100% 100%,30px 100%);
    }
    
    .row.left.bottom::before,
    .row.right.bottom::before{
      transform:scaleY(-1);
    }
    <div class="row right bottom"></div>
    <div class="row left" style="height:100px"></div>
    <div class="row left bottom"></div>
    <div class="row right" style="height:200px"></div>
    <div class="row right bottom" style="height:100px"></div>
    <div class="row left" style="height:100px"></div>