Search code examples
htmlimagecssradial-gradients

Multiple background images, gradient and image, matching scale of image


I have a background made up of an image and a gradient.

http://codepen.io/anon/pen/RWrKGv

I'm using the following CSS:

.row {
  display: block;
  width: 50%;
  min-height: 150px;
  min-height: 750px;
  background: -webkit-radial-gradient( 50% 50%, circle farthest-side, rgb(201, 2, 10) 0%, rgb(0, 0, 0) 100%), url("https://dl.dropboxusercontent.com/u/11795964/deer-antlers.jpg");
  background-blend-mode: multiply;
  background-size: contain;
  background-position: 0 0;
  background-repeat: no-repeat;
}

When you resize the page, the image begins to scale while the gradient stays the same size. I would like them to scale at the same time, so that you do not see the image being cut.

gradient not scaling


Solution

  • The gradient doesn't scale because the dimensions of the container element determines the size of the gradient. So, irrespective of whether page is resized or not, the element (and in turn, the gradient) are 750px tall. (Note that you have two min-height settings and so the latter would override former). You can find more info about the calculation of size for gradient images in my answer here.

    Now coming to the case with the image, even though you have set the background-size as contain (which is also the default size for gradients), images have an intrinsic aspect ratio and hence they are automatically scaled in such a way that its height and width can fit inside the background positioning area while preserving its aspect ratio. So, as the width of the element changes (which happens due to the 50% width setting on the container) the height of the image also changes to preserve the ratio.

    So, in short, your current settings will not achieve what you wish to, because (a) the gradient will not scale in height as it has no intrinsic aspect ratio (and there is no way to set one as far as I am aware) and (b) the image will scale.

    Making the image scale without maintaining the aspect ratio may not be a desirable case and scaling gradients in the same way is not possible even if it is assigned a background-size (because then it won't scale and gets rendered as fixed size with/without repeat).

    In my opinion the best fix is to assign the container's dimensions such that it is always proportionate to the dimensions of the image that it is going to hold. For example, in the below snippet, I have used an image which is 500px wide x 750px tall and so I have assigned the height and width of container as 100vh and 150vh respectively. This would mean that when the height of the the viewport changes, both height and width of the container will change. This would in-turn mean that even when the image is scaled its aspect ratio matches with the container and so will occupy the full available space.

    .row {
      display: block;
      width: 100vh;
      min-height: 150vh;
      background: -webkit-radial-gradient(50% 50%, circle farthest-side, rgb(201, 2, 10) 0%, rgb(0, 0, 0) 100%), url("http://lorempixel.com/500/750/nature/1");
      background: radial-gradient(circle farthest-side at 50% 50%, rgb(201, 2, 10) 0%, rgb(0, 0, 0) 100%), url("http://lorempixel.com/500/750/nature/1");
      background-blend-mode: multiply;
      background-size: contain;
      background-position: 0 0;
      background-repeat: no-repeat;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
    <div class="row">
    </div>