Search code examples
cssbackground-imagebackground-position

Two background images, one with a percentage size and the other one cover what's left?


I have a div and I would like half of the div to be covered in a gradient and the other half to be a normal image but with the same effect as background-size:cover; and have it fill up the remaining space to the right of the gradient. Is this possible?

div {
  width:100%;
  height:400px;
  background-image:url(http://placehold.it/100x100);
  background-size: 50% cover;
  background-position: 100% center;
  background-repeat:no-repeat;
}
  div:before {
    content:"";
    display:block;
    width:50%;
    height:100%;
    background-image: linear-gradient(red, yellow);
  }
<div></div>

Unfortunately this doesn't seem to work. I can use background-size: 50% auto; but that doesn't give me quite what I am looking for. I realize I could just split this into two divs, but I just wanted to see if it was possible to do it with one.


Solution

  • Use multiple background and some padding, background-origin trick. The idea is to define padding as half the width and put the image on the content-box which will be the other half.

    You have to use vw unit but there is a small drawback as it consider the width of the scroll. It can also be an issue if the div is not meant to be a full width div.

    .box {
      padding-left:50vw;
      height:300px;
      background:
        linear-gradient(red, yellow) left/50vw 100%,
        url(http://placehold.it/400x400) center/cover content-box;
      background-repeat:no-repeat;
    }
      
    body {
      margin:0;
    }
    <div class="box"></div>

    Or simply use both pseudo element:

    .box {
      height:300px;
      position:relative;
    }
    div::before,
    div::after {
      content:"";
      position:absolute;
      top:0;
      bottom:0;
      width:50%;
    }
    div::before {
      left:0;
      background:linear-gradient(red, yellow);
    }
    div::after {
      right:0;
      background:url(http://placehold.it/400x400) center/cover;
    }
      
    body {
      margin:0;
    }
    <div class="box"></div>