Search code examples
cssimageintersectiondiagonal

Diagonal cut images with offset, working on all screen sizes


I need to achieve this block element:

diagonal split image

Which can have elements on top/bottom. My problem is to keep the diagonal split always in line in any screen resolution.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

img {
  display: inline-block;
  width: 100%;
}

.content {
  padding: 50px;
  height: 50vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
}

.horizontalbar {
  display: flex;
  height: 500px;
  width: 100%;
  position: relative;
}

.horizontalbar img {
  position: absolute;
  -o-object-fit: cover;
  object-fit: cover;
  height: 100%;
  width: calc(100% - 5vw);
}

.horizontalbar img.image1 {
  left: 0;
  top: 5vw;
  -webkit-clip-path: polygon(0 0, calc(100% - 25vw) 0%, 25vw 100%, 0% 100%);
  clip-path: polygon(0 0, calc(100% - 25vw) 0%, 25vw 100%, 0% 100%);
}

.horizontalbar img.image2 {
  right: 0;
  top: -5vw;
  -webkit-clip-path: polygon(calc(100% - 25vw) 0, 100% 0%, 100% 100%, calc(25vw) 100%);
  clip-path: polygon(calc(100% - 25vw) 0, 100% 0%, 100% 100%, calc(25vw) 100%);
}
<div class="content">
  <div class="horizontalbar">
    <img src="https://source.unsplash.com/900x1300/?women" alt="" class="image1">
    <img src="https://source.unsplash.com/900x1400/?man" alt="" class="image2">
  </div>
</div>

live codepen

I assume with some js to keep adjusting the clip according to the screensize, but what math/calculations need to be done here? Is there a better way to achieve this?


Solution

  • simplify your clip-path and control the background-position to create the top and bottom spaces:

    .box {
      display: flex;
      height: 400px;
    }
    
    .box>div {
      flex: 1;
    }
    
    .box>div:first-child {
      margin-right: -10vw;
      background: url(https://picsum.photos/id/1018/800/800) top 50px center /cover no-repeat;
      clip-path: polygon(0 0, 100% 0, calc(100% - 20vw - 5px) 100%, 0 100%);
    }
    
    .box>div:last-child {
      margin-left: -10vw;
      background: url(https://picsum.photos/id/125/800/800) bottom 50px center /cover no-repeat;
      clip-path: polygon(calc(20vw + 5px) 0, 100% 0, 100% 100%, 0 100%);
    }
    <div class="box">
      <div></div>
      <div></div>
    </div>

    Also like below:

    .box {
      display: flex;
      height: 400px;
    }
    
    .box>div {
      flex: 1;
      position:relative;
    }
    .box > div::before {
      content:"";
      position:absolute;
      left:0;
      right:0;
      height:calc(100% - 50px);
      background: var(--i) center /cover no-repeat;
    }
    
    .box>div:first-child {
      margin-right: -10vw;
      clip-path: polygon(0 0, 100% 0, calc(100% - 20vw - 5px) 100%, 0 100%);
    }
    .box>div:first-child::before {
      bottom:0;
    }
    
    .box>div:last-child {
      margin-left: -10vw;
      clip-path: polygon(calc(20vw + 5px) 0, 100% 0, 100% 100%, 0 100%);
    } 
    .box>div:last-child::before {
      top:0;
    }
    <div class="box">
      <div style="--i:url(https://picsum.photos/id/1018/800/800)"></div>
      <div style="--i:url(https://picsum.photos/id/125/800/800)"></div>
    </div>