Search code examples
htmlcssbackgroundpolygon

How to make a background like the one in the picture using polygon


I'm wondering how to make such a header using the clip path polygon command. It would be simpler to insert an image but I'd like to learn and use animation for this in CSS which I can do.

When I tried different methods the divs were far apart and there were various problems with it. I would appreciate your advice.

This is my code and current progress:

Example Image

body {
  font-family: "Anonymous Pro", monospace;
  font-weight: 400;
  font-size: 16px;
  line-height: 1, 7;
  color: #777;
  padding: 30px;
}

.header {
  height: 80vh;
  background-image: radial-gradient(
    circle at 18.7% 37.8%,
    rgb(238, 226, 226) 0%,
    rgb(211, 219, 223) 90%
  );

  clip-path: polygon(100% 11%, 100% 77%, 0 100%, 0 0);
  backface-visibility: hidden;
  background-position: top;
  background-size: cover;
  color: black;
  position: relative;
  animation-name: movefromright;
  animation-duration: 1.7s;
  animation-timing-function: ease-out;
}

.image {
  background-image: url(img/logo2.png);
  height: 80vh;
  position: relative;
  background-size: cover;
  background-position: top;
  backface-visibility: hidden;
  animation-name: movefromleft;
  animation-duration: 1.7s;
  animation-timing-function: ease-out;
}
<body>
    <header class="header">
      <div class="image"></div>
      <div class="text-box">
        <div class="header-button">
          <a href="#zawartosc" class="btn btn-blue">Przejdź dalej</a>
        </div>
      </div>
    </header>

I would like to get this effect:

Source: Canva


Solution

  • So there are are a few ways that I'd work on handling this. First clip-path doesn't really allow you to do things "outside" of it. So you won't be able to get both the clipped background and the red and blue. I made two snippets for you to check out.

    This first snippet keeps the markup as it is, and uses ::before and ::after elements to make the background. The ::before creates the red and blue, and the ::after has the clipped background that includes the radial gradient.

    body {
      font-family: "Anonymous Pro", monospace;
      font-weight: 400;
      font-size: 16px;
      line-height: 1, 7;
      color: #777;
      padding: 30px;
    }
    
    .header {
      height: 80vh;
      position: relative;
    }
    
    .header::before {  
      background-image: linear-gradient(180deg, rgba(255, 0, 0, 1) 0%, rgba(255, 0, 0, 1) 50%, rgba(0, 15, 240, 1) 50%, rgba(0, 15, 240, 1) 100%);
      bottom: 0;
      color: black;
      content: '';
      left: 0;
      position: absolute;
      right: 0;
      top: 0;
      z-index: -2;
    }
    
    .header::after {
      animation-name: movefromright;
      animation-duration: 1.7s;
      animation-timing-function: ease-out;
      background-image: radial-gradient( circle at 18.7% 37.8%, rgb(238, 226, 226) 0%, rgb(211, 219, 223) 90%);
      backface-visibility: hidden;
      bottom: 0;
      clip-path: polygon(100% 11%, 100% 77%, 0 100%, 0 0);
      content: '';
      left: 0;
      position: absolute;
      right: 0;
      top: 0;
      z-index: -1;
    }
    
    .image {
      background-image: url(img/logo2.png);
      height: 80vh;
      position: relative;
      background-size: cover;
      background-position: top;
      backface-visibility: hidden;
      animation-name: movefromleft;
      animation-duration: 1.7s;
      animation-timing-function: ease-out;
    }
    <header class="header">
      <div class="image"></div>
      <div class="text-box">
        <div class="header-button">
          <a href="#zawartosc" class="btn btn-blue">Przejdź dalej</a>
        </div>
      </div>
    </header>

    This second snippet changes the markup, which I would recommend. This would allow you to have everything inside the clipped container and have the blue and red background. This would also allow you to not have to mess with z-index and pseudo-elements. Neither of those are bad, but I think it would be easier to just wrap the header and apply a background there.

    The content of the clipped element will sill need to fit inside the clipped container. There are a few ways that you can handle that. If you make the clipped container a sibling element and set it to position: absolute; it will sit behind everything. To do this, you'd need to make the header element (that has the red and blue background) have position: relative;.

    I'd also note that your .image div takes up the full height, that is what you aren't seeing the contents when it's inside the clipped container.

    body {
      font-family: "Anonymous Pro", monospace;
      font-weight: 400;
      font-size: 16px;
      line-height: 1, 7;
      color: #777;
      padding: 30px;
    }
    
    header {
      background-image: linear-gradient(180deg, rgba(255, 0, 0, 1) 0%, rgba(255, 0, 0, 1) 50%, rgba(0, 15, 240, 1) 50%, rgba(0, 15, 240, 1) 100%);
    }
    
    .header-wrapper {
      height: 80vh;
      background-image: radial-gradient( circle at 18.7% 37.8%, rgb(238, 226, 226) 0%, rgb(211, 219, 223) 90%);
      clip-path: polygon(100% 11%, 100% 77%, 0 100%, 0 0);
      backface-visibility: hidden;
      background-position: top;
      color: black;
      position: relative;
      animation-name: movefromright;
      animation-duration: 1.7s;
      animation-timing-function: ease-out;
    }
    
    .image {
      background-image: url(img/logo2.png);
      height: 80vh;
      position: relative;
      background-size: cover;
      background-position: top;
      backface-visibility: hidden;
      animation-name: movefromleft;
      animation-duration: 1.7s;
      animation-timing-function: ease-out;
    }
    <header>
      <div class="header-wrapper">
        <div class="image"></div>
        <div class="text-box">
          <div class="header-button">
            <a href="#zawartosc" class="btn btn-blue">Przejdź dalej</a>
          </div>
        </div>
      </div>
    </header>

    Without seeing the full design and knowing how it works, I'm not sure I can give you a better answer, but this should give you what you need.