Home > Back-end >  How to fit div with background-image into a parent container, without causing scrolling, given the c
How to fit div with background-image into a parent container, without causing scrolling, given the c

Time:01-13

I have this super basic minimal demo, which shows a square image with border radius to make it look like a circle. It then rotates slowly. However, because it is a square, as it rotates, because it goes into a diagonal, the horizontal width grows and shrinks back, repeatedly. This is causing the parent to resize. I don't want the parent to resize, I want the parent to stay 100% width, and have the content fit inside. See the problem here (image courtesy of this):

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.container {
  display: flex;
  flex-shrink: 0;
  padding: 64px;
  width: 100vw;
}

.bg-image {
  background-image: url(https://i.imgur.com/9mhwcLH.png);
  background-size: contain;
  -webkit-transform-origin: 50% 50%;
  -ms-transform-origin: 50% 50%;
  transform-origin: 50% 50%;
  background-position: center center;
  background-repeat: no-repeat;
  -webkit-animation: spin 512s linear infinite;
  animation: spin 512s linear infinite;
  height: 0;
  padding-top: 100%;
  background-size: contain;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  border-radius: 50%;
}
<div >
  <div ></div>
</div>

There are two ways this could work, I don't have a preference how it is solved, either way would be fine for me.

  1. Since it is carved into a circle, the parent width should never change (because it's a circle..). Even though the underlying div is still a square... This would mean that the change in the width of the square div should have no effect on the parent.
  2. Or alternatively, if it is at all possible, you could potentially shrink down the child so that at a 45 degree angle, that fits perfectly into the parent, and as it rotates it just gets smaller than the parent. Either way works, knowing how to do both would be very advantageous and helpful, so I can choose when the situation is right, but knowing just one way is also enough to solve my problem.

Any ideas how to fix this and get it to work, not resizing the parent (so the parent width is constant, or so the child doesn't have an impact on the parent width)?

CodePudding user response:

I made some changes to inherit the parent height and width.

Note parent height and width will be in ratio of 1:1 so the child will be in radius as you expected

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.container {
  display: flex;
  flex-shrink: 0;
  padding: 64px;
  height:300px;
  width: 300px; /* parent height and with will be in ratio of 1:1*/
}

.bg-image {
  background-image: url(https://i.imgur.com/9mhwcLH.png);
  background-size: contain;
  -webkit-transform-origin: 50% 50%;
  -ms-transform-origin: 50% 50%;
  transform-origin: 50% 50%;
  background-position: center center;
  background-repeat: no-repeat;
  -webkit-animation: spin 512s linear infinite;
  animation: spin 512s linear infinite;
  height: 0;
  /*padding-top: 100%;*/
  background-size: contain;
  /*position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;*/
  border-radius: 50%;
  width:100%;
  height:100%;/* inherits the parent's height and width */
}
<div >
  <div ></div>
</div>

CodePudding user response:

You may clip the overflowing part of the container as follows

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.container {
  display: flex;
  flex-shrink: 0;
  padding: 64px;
  width: 100vw;
  overflow-x: clip;
}

.bg-image {
  background-image: url(https://i.imgur.com/9mhwcLH.png);
  background-size: contain;
  -webkit-transform-origin: 50% 50%;
  -ms-transform-origin: 50% 50%;
  transform-origin: 50% 50%;
  background-position: center center;
  background-repeat: no-repeat;
  -webkit-animation: spin 512s linear infinite;
  animation: spin 512s linear infinite;
  height: 0;
  padding-top: 100%;
  background-size: contain;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  border-radius: 50%;
}
<div >
  <div ></div>
</div>

  • Related