Trapezoid Sections, Clipping Background Images

2020-04-28 09:04发布

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

2条回答
贼婆χ
2楼-- · 2020-04-28 09:27

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>

查看更多
该账号已被封号
3楼-- · 2020-04-28 09:51

I've got a pretty similar project in the pipeline, so I figured why not take a stab at this. Depending on the need, I think 2x containers overlapped and skewed will work.

However, if the top and bottom are skewed at different angles that won't work... So the best bet is Pseudo elements absolutely positioned and using CSS clip-path. I used this tool to easily create clip paths.

I'm doing it this way to avoid clipping the content of each section, but that might not matter in your case.

.container {
  width: 80vw;
  margin: 0 auto;
  overflow: hidden;
}

section {
  min-height: 40vh;
  position: relative;
  padding: 2rem;
}

.sec1 {
  background-color: #FFFFFF;
}

.sec2 {
  background: #01579B;
}
.sec2:before {
  content: '';
  position: absolute;
  background-color: #01579B;
  height: 3rem;
  bottom: 100%;
  right: 0;
  left: 0;
  z-index: 10;
  -webkit-clip-path: polygon(0 0, 0% 100%, 100% 100%);
          clip-path: polygon(0 0, 0% 100%, 100% 100%);
}
.sec2:after {
  content: '';
  position: absolute;
  background-color: #01579B;
  height: 7rem;
  top: 100%;
  right: 0;
  left: 0;
  z-index: 10;
  -webkit-clip-path: polygon(100% 0, 0 0, 100% 100%);
          clip-path: polygon(100% 0, 0 0, 100% 100%);
}
.sec2 .decor {
  position: absolute;
  background-color: #D7CCC8;
  height: 6rem;
  bottom: 100%;
  right: 0;
  left: 50%;
  z-index: 5;
  -webkit-clip-path: polygon(100% 0, 0 100%, 100% 100%);
          clip-path: polygon(100% 0, 0 100%, 100% 100%);
}

.sec3 {
  background-color: #0288D1;
}
.sec3:after {
  content: '';
  position: absolute;
  background-color: #0288D1;
  height: 7rem;
  top: 100%;
  right: 0;
  left: 0;
  z-index: 10;
  -webkit-clip-path: polygon(0 0, 0 100%, 100% 0);
          clip-path: polygon(0 0, 0 100%, 100% 0);
}
<div class="container">
	<section class="sec1">Section 1 Content</section>
	<section class="sec2">
		<span class="decor">
<!-- unfortunatly, I needed another element -->
		</span>
		Section 2 Content
	</section>
	<section class="sec3">
		Section 3 Content
	</section>
	<section class="sec4">
		Section 4 Content
	</section>
</div>

The only problem I can see with this is if you need an image background. In which case you might want to use a complex polygon as the mask for the entire section.

查看更多
登录 后发表回答