skip to Main Content

I’m trying to create a landing page with a background image and a white rectangle with a "window".

background and rectangle

I can’t get the css right. In figma, Im using the "window" rectangle as a mask on the white rectangle to show the page background, however I don’t know, how/if that same masking technique works in html css (I imagine it needs to be more hacky, like line up the background image and window background image so it looks like its transparent?).

I’ve tried a few things implementations with little success.

Right now it looks like:

enter image description here

which is close, but you’ll see the image in the "window" is ceneterd, and I’d like it to line up with the page background.

The page needs to be responsive, and the image should maintain its aspect ratio.

.backgroundImage {
  background-image: url('../../public/alabama-hills.jpg');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-attachment: fixed;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}


/* Create the white rectangle */

.whiteRectangle {
  position: absolute;
  border-radius: $border-radius;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: white;
  width: 80%;
  height: 80%;
  display: flex;
  align-items: center;
  padding: 1rem;
  justify-content: space-between;
}


/* Create the nested rectangle acting as a mask */

.mask {
  position: relative;
  width: 50%;
  height: 100%;
  border-radius: $border-radius;
  overflow: hidden;
}


/* Position the pseudo-element to match the background image */

.mask::before {
  content: "";
  background-image: url('../../public/alabama-hills.jpg');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-attachment: fixed;
  position: absolute;
  top: 0%;
  right: 0%;
  width: 100%;
  height: 100%;
}
<div className={styles.backgroundImage}></div>
<div className={styles.whiteRectangle}>
  <div />
  <div className={styles.mask}></div>
</div>

3

Answers


  1. A rounded box and some box-shadow can do it:

    body {
      min-height: 100vh;
      margin: 0;
      display: grid;
      background: url(https://picsum.photos/id/10/800/400) center/cover;
    }
    
    .box {
      height: 80vh;
      width: 40vw;
      margin: auto 10vw auto auto;
      border: 10px solid #fff;
      border-radius: 20px;
      /* two shadows, one equal to width and another ot the radius */
      box-shadow: -40vw 0 #fff,-20px 0 #fff;
    }
    <div class="box"></div>

    Or with some pseudo elements if you want better control of the width of the window

    body {
      min-height: 100vh;
      margin: 0;
      display: grid;
      background: url(https://picsum.photos/id/10/800/400) center/cover;
    }
    
    .box {
      height: 80vh;
      width: 80vw;
      margin: auto;
      display: grid;
      grid-template-columns: 1fr 40%; /* adjust the 40% */
    }
    .box:before,
    .box:after{
      content:"";
      border: 10px solid #fff;
      border-radius: 20px;
    }
    .box:before {
      background: #fff;
    }
    .box:after {
      box-shadow: -40px 0 #fff;
    }
    <div class="box"></div>
    Login or Signup to reply.
  2. I think this work better with flex as you can have content one side and photo other side anything possible if you want to use media query that also easy with flex. You can try with grid also.

    body {
      min-height: 100vh;
      margin: 0;
      display: grid;
      background: url(https://www.goodfreephotos.com/cache/united-states/california/other/alabama-hills-landscape-in-california_800.jpg?cached=1522511648) center/cover;
    }
    
    .box {
      margin: auto;
      width: 80%;
      height: 80%;
      display: flex;
      border-radius: 10px;
      border: thick solid #fff;
    }
    
    .box .content {
      background-color: white;
      width: 50%;
      height: 100%;
    }
    
    .content-t {
      border-radius: 10px;
      margin:-2px;
      width: 50%;
      height: auto;
      border: thick solid #fff;
    }
    <div class="box">
      <div class="content">
      </div>
      <div class="content-t">
      </div>
    </div>
    Login or Signup to reply.
  3. I made this codepen to solve the issue: https://codepen.io/JW-Based/pen/bGmojNo

    <div class="backer">
    
    <div class="hero">
        <div class="hero_left"></div>
        <div class="hero_right">
            <div class="hero_right_window"></div>
        </div>
    
    </div>
    

    so you have the wrapper ‘backer’ that has the background image applied to it. the div with class ‘hero’ will be the parent div that will hold your opaque ‘hero_left’ and transparent ‘hero_right’ divs.’hero’ itself will have a transparent background applied to it while ‘hero_left’ will have a background color ‘white’ assigned to it. ‘hero_right’ will have the child ‘hero_right_window’ within it. this is structured so that we can have the border radii balanced between the parent and children.

    .hero_left {
    background: white;
    height: 100%;
    flex-basis: 50%;
    border-radius: 10px 0px 0px 10px;
    border: 5px solid white;}
    
    .hero_right {
    height: 100%;
    flex-basis: 50%;
    border: 5px solid white;
    border-radius: 0px 10px 10px 0px;}
    

    you can see that we have opposing border radii set here and

    .hero_right_window {
    height:100%;
    outline: solid white;
    border-radius: 8px 0px 0px 8px;}
    

    here we set an outline to not add more height to the child div, ‘hero_right_window’ and set the radii accordingly. you may have to tweak the outline thickness to avoid a clear ‘deadzone’ between the outline and the parent div.

    Anyway, small amount of added css here to achieve what you wanted. let me know if you need an update.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search