3

I'm trying to set up a banner which features an overlay with a cutout in it. Below the overlay is an image.

I'm trying to figure out how to create this in HTML and CSS, my experiments so far have seen me play with psuedo elements but am struggling to recreate the design in the shape and position shown below.

My current HTML looks like this:

<header class="main" style="background-image: url(./assets/images/bg-hero.jpg)">
    <div class="container">
        <div class="row">
            <div class="col-12">
                <div class="row row--no-pad">
                    <div class="col-6">
                        <a href="/">
                            <img src="./assets/images/logo.png" alt="">
                        </a>
                    </div>

                    <div class="col-6">
                        <a href="#" class="menu-toggle"></a>
                    </div>
                </div>

                <div class="row">
                    <div class="banner">
                        <div class="row">
                            <div class="col-12">
                                <h1>Lorem ipsum dolor sit amet</h1>

                                <p>Lorem ipsum dolor sit amet lorem ipsum dolor sit amet, L lorem ipsum dolor sit amet.</p>

                                <a href="#" class="button button--primary">View our services</a>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</header>

Here's the design:

enter image description here

Thanks,

Ben

0Neji
  • 1,038
  • 1
  • 14
  • 36

4 Answers4

5

What you're looking for is known as image clipping. There are many articles on the web that cover how to do it with CSS (here is one). The process is really straight forward as it only requires one line of CSS to accomplish this task. You'll need to utilize clip-path in order to get this done, and I highly recommend reading the documentation on it.

Building the clip-path can be difficult depending on what you're going for, but Clippy is an online clip path assistant that is very helpful. However, based on the image you supplied, the following will work:

html, body {
  margin: 0;
  height: 100%;
  background-color: #124;
  background-image: linear-gradient(to right, #111, #124);
  background-image: -webkit-linear-gradient(to right, #111, #124);
}
.background-image {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/2940219/GIF_Koi_Pond.gif');
  background-size: cover;
  background-position: center;
  clip-path: polygon(56% 0, 78% 50%, 56% 100%, 31% 100%, 52% 50%, 28% 0);
}
.main-content {
  position: absolute;
  top: 0;
  left: 0;
  color: #fff;
  display: flex;
  justify-content: center;
  flex-direction: column;
  height: 100%;
  padding: 15px;
}
.main-content h1 {
  width: 250px;
  margin: 0;
}
.main-content a {
  color: #fff;
  background-color: #3a7;
  text-decoration: none;
  padding: 5px 25px;
  width: 150px;
  text-align: center;
}
<div class="background-image"></div>
<div class="main-content">
  <h1>Lorem ipsum dolor sit amet</h1>
  <p>Lorem ipsum dolor sit amet lorem ipsum dolor sit amet, L lorem ipsum dolor sit amet.</p>
  <a href="#" class="button button--primary">View our services</a>
</div>

The part you are the most interested in is:

clip-path: polygon(56% 0, 78% 50%, 56% 100%, 31% 100%, 52% 50%, 28% 0);

Also, don't forget that clip-path has a -webkit version that needs to be accounted for.

clip-path: polygon(56% 0, 78% 50%, 56% 100%, 31% 100%, 52% 50%, 28% 0);
-webkit-clip-path: polygon(56% 0, 78% 50%, 56% 100%, 31% 100%, 52% 50%, 28% 0);

Another thing to remember is that when you apply clip-path to an element such as a div, you're not just clipping the background-image, but rather clipping the entire element.

Hazel へいぜる
  • 2,751
  • 1
  • 12
  • 44
1

Image clipping is definitely an option, although if you wanted to go for something more traditional you could use borders like this:

#cutBox{
  width: 100%;
  height: 600px;
  background-image: url('https://wallpaperplay.com/walls/full/7/2/4/272374.jpg');
  background-size: cover;
  display: flex;
}

#leftPane, #rightPane{
  background-color: midnightblue;
}

#leftPane, #rightPane{
  height: 100%;
  width: 40%;
}

#leftTri{
  border-left: 100px solid midnightBlue;
  border-top: 300px solid transparent;
  border-bottom: 300px solid transparent;
  margin-right: 200px;
}
#rightTri{
  border-left: 100px solid transparent;
  border-top: 300px solid midnightblue;
  border-bottom: 300px solid midnightblue;
}

#leftPane > .pane-text{
  position: relative;
  color: white;
  top: 40%;
  font-size: 26px;
  margin-left: 60%;
  right: -10px;
}

.subtext{
  margin-left: 20px;
  font-size: 18px;
}
<div id="cutBox">
  <div id="leftPane">
    <div class="pane-text">
      Lorem Ipsum
      <div class="subtext">
        dolor sit amet
      </div>
    </div>
  </div>
  <div id="leftTri">
  </div>
  <div id="rightTri">
  </div>
  <div id="rightPane">
  </div>
</div>

It might look a little odd because of the small viewport but it generally works pretty well.

Libra
  • 2,544
  • 1
  • 8
  • 24
1

You can use clip-path property to achieve the affect above.

For example this polygon will create a mask that will create a star shape.

.star {
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

Here's a tutorial on clip-path

Miles
  • 764
  • 2
  • 11
  • 20
1

you can also use multiple background with gradient hiding partially another background-image:

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

header {
  background: linear-gradient(60deg, rgb(0, 0, 36) 66.6%, transparent 66.66%, transparent 86%, rgb(0, 0, 36) 86.3%) top left no-repeat, linear-gradient(120deg, rgb(0, 0, 36) 66.6%, transparent 66.66%, transparent 86%, rgb(0, 0, 36) 86.3%) bottom left no-repeat, url(https://placeimg.com/640/480/nature/5) center right;
  background-size: 100% 50%, 100% 50%, auto;
  /*demo purpose*/
  position: relative;
  display: flex;
  justify-content: space-around;
  flex-direction: column;
  color: white;
  max-width: 800px;
  min-height:250px;
  box-shadow: 0 0 1px;
  padding-right: 250px;
  margin: auto;
  padding-left:1em;
}

body {
  background: rgb(0, 0, 36)
}

nav {
  position: absolute;
  right: 3%;
  top: 3em;
  border-top: 3px solid;
  border-bottom: 3px solid;
}

nav b {
  display: block;
  width: 2em;
  height: 3px;
  background: white;
  margin: 5px 0
}
<header>
  <nav><b></b></nav>
  <h1>title</h1>
  <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
    thus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
    <a>link</a>
</header>

tune start/stop gradient values to your needs, this is an example.

G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129