cssbackground-positionbackground-sizebackground-repeat

How exactly background-size and background-repeat works?


Here's an example. I'd like to crop background image, and then to use cropped image as background for a bigger (in size) element. I mean the div is bigger than its background, and I don't need repetition. Now when background-repeat is uncommented, element disappear. But I supposed that it will show cropped unrepeated background.

#div {
  background-image: url(http://dummyimage.com/600x400/000/fff);
  padding: 10px;
  width: 100px;
  height: 100px;
  background-position: 0px -100px;
  background-size: 100px 100px;
  background-repeat: no-repeat;  /*comment this*/
  position: absolute;
}
<div id="div"></div>


Solution

  • The background disappears when the background-repeat: no-repeat setting is added because of the position that is assigned to the background. It is set at 0px -100px with respect to the origin. You haven't set any value for background-origin and so the default value (which is, padding-box would be used) and the height of the image is only 100px. Because of this when you instruct the browser to not repeat the image, there is nothing in the visible area.

    For the case illustrated in demo, the image doesn't need to be cropped because its size is only 100 x 100 (set using background-size) and the div box's size (along with padding of 10px on all sides) is bigger than the image (refer to the below snippet to see this in action).

    If you mean to say that you'd like to scale the 600 x 400 image into 100 x 100 using background-size property and display it within the div then you could do it as shown in the below snippet itself.

    .div {
      /*position: absolute; commented out for demo */
      background-image: url(http://dummyimage.com/600x400/000/fff);
      padding: 10px;
      width: 100px;
      height: 100px;
      /*background-position: 0px -100px; - this makes it positioned above the viewable area of the box container, so remove it */
      background-size: 100px 100px;
      background-repeat: no-repeat;
      border: 1px solid red;  /* just to show how box is bigger than image */
    }
    
    /* If the image has to be centered within the div */
    .div.centered { background-position: 50% 50%; }
    
    /* Just for demo */
    div{ margin: 10px;}
    <div class="div"></div>
    <div class="div centered"></div>


    On the other hand, if you were intending to use background-position to specify the area from where the cropping should be done then it is not possible to do that way. For such a case, you should avoid using background-size and just use background-position like in the below snippet.

    Here, by specifying background-position as -240px -140px, the portion of the image that is present within the coordinates (240,140) to (360,260) on the image would be displayed within the box. It shows 120 x 120 pixels of image due to the size of the box (including padding).

    .div {
      position: absolute;
      background-image: url(http://dummyimage.com/600x400/000/fff);
      padding: 10px;
      width: 100px;
      height: 100px;
      background-position: -240px -140px;
      background-repeat: no-repeat;
      border: 1px solid red;  /* just to show how box is bigger than image */
    }
    
    /* Just for demo */
    div{ margin: 10px; }
    <div class="div"></div>