Search code examples
htmlcssbackground-imagecss-transformsclip-path

Trapezoid Sections, Clipping Background Images


I am trying to create a web layout with trapezoid shapes like in the image attached. With the addition that each section has a background-image that fills the background with cover or a like result.

The first section (dark blue) I have achieved simply using skew and two divs as demonstrated below.

However, I can't create the following section, where it skews two ways. I have attempted using clip-path without luck. Then the final section needs to square-off again.

HTML

<section id="my_section">
        <div id="my_section_bg"></div>
        <div id="my_section_content">
            <!-- any typical content, text/images here -->
        </div>
    </section>

CSS

#my_section {
    padding-top: 80px;
    padding-bottom: 90px;

    background-color: rgba(74,90,119,.5);

    transform: skewY(-4deg);
}

#my_section_bg {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;

    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    background-image: linear-gradient(
        to bottom,
        rgba(29,44,71,.85) 0%,
        rgba(29,44,71,1) 100%
        ), url("./assets/my_bg_img.jpeg");
    background-color: rgba(29,44,71,1);

    transform: skewY(8deg);
}

#my_section_content {
    transform: skewY(4deg);
}

Desired section design


Solution

  • You can simply hide a part of the second skewed section under the first one to create this effect. Same thing for the last section:

    Here is a basic example:

    .box {
      min-height:250px;
      position:relative;
      overflow:hidden;
      transform-origin:left; /*this will do the magic*/
      max-width:1000px;
      margin:auto;
    }
    .box:before {
      content:"";
      position:absolute;
      top:-100px;
      left:0;
      right:0;
      bottom:-100px;
      transform-origin:left;
      background:var(--img,red) center/cover;
    }
    
    .first {
      transform:skewY(5deg);
      z-index:2;
      --img:url(https://picsum.photos/800/600?image=0)
    }
    .first:before {
      transform:skewY(-5deg);
    }
    
    .second {
      transform:skewY(-5deg);
      z-index:1;
      --img:url(https://picsum.photos/800/600?image=1069)
    }
    .second:before {
      transform:skewY(5deg);
    }
    
    .last {
      --img:url(https://picsum.photos/800/600?image=1053);
      margin-top:-100px;
    }
    <div class="first box">
    
    </div>
    <div class="second box">
    
    </div>
    
    <div class="last box">
    
    </div>

    Or with clip-path you can do like below (adjust the 50px everywhere to control the angles)

    .box {
      min-height:250px;
      position:relative;
      overflow:hidden;
      max-width:1000px;
      margin:auto;
    }
    .first {
      clip-path:polygon(0 0,100% 50px, 100% 100%,0 100%);
      background:url(https://picsum.photos/800/600?image=0) center/cover;
    }
    
    .second {  
      clip-path:polygon(0 50px,100% 0, 100% 100%,0 calc(100% - 50px));
      z-index:1;
      margin:-50px auto;
      background:url(https://picsum.photos/800/600?image=1069) center/cover;
    }
    
    .last {
      background:url(https://picsum.photos/800/600?image=1053) center/cover;
    }
    <div class="first box">
    </div>
    <div class="second box">
    </div>
    <div class="last box">
    </div>