CSS 背景图像过渡效果未按预期工作

CSS background-image transitions effects not working as expected

好的,所以我正在使用 div 和背景图片处理悬停时的滑动效果。背景图像使用外部 div 最大宽度和内部 div 以及底部填充百分比来保持纵横比。

这里有些地方我不明白。

  1. 令我感到非常惊讶的是,我的 %200 背景位置仅将图像推过几个像素,最后,需要大量的 7100% 才能完全移动图像,因此重复的图像完全可见。
  2. 当我将 padding-bottom 设置为超过 54% 时,过渡和一切都停止工作。
  3. 这个“7100%”似乎在 chrome、firefox 和 opera 中产生了正确的效果,但在 safari 中却没有。

我的fiddle,想法? https://jsfiddle.net/riegersn/a3mnr9um

.container {
      max-width: 480px;
    }


.project {
  margin-bottom: 15px;
  cursor: pointer;
  overflow: hidden;
  width: 100%;
  background-position: center center;
  background-repeat: repeat-x;
  background-size: contain;
  transition: all 0.2s ease-out;
  padding-bottom: 54%;
  &:hover {
    background-position: 7100% 50%;
  }
}

在位置背景图像中使用百分比时,会变得有些复杂。

Moving a background image by X% means it will align the X% point in the image to the X% point in the container. For example, 50% means it will align the middle of the image with the middle of the container. 100% means it will align the last pixel of the image with the last pixel of the container, and so on.


Src: https://css-tricks.com/almanac/properties/b/background-position/)


这里也很好地解释了它是如何工作的:how-does-css-computation-for-background-percentages-work


我可以推荐一个伪元素,您可以在其中使用 transform,它在动画方面比 background-position 表现更好。

使用伪图像,您还可以缩放、旋转、倾斜、来回移动等等,这些仅靠背景图像是不可能实现的。

在下面的示例中发生的是,我将伪造的宽度设为 project 的两倍,将其宽度的一半置于左侧(left: -100%,其中 100% 来自其父级)然后,当鼠标悬停时,我将其向后移动,使左侧变为 0 (transform: translateX(50%)),其中 translateX(50%) 表示将其向右移动其自身宽度的一半。

.container {
  max-width: 480px;
}

.project {
  position: relative;
  margin-bottom: 15px;
  cursor: pointer;
  overflow: hidden;
  width: 100%;
  padding-bottom: 54%;
  background-size: 0;
}
.project::before {
  content: '';
  position: absolute;
  left: -100%; top: 0;
  width: 200%; height: 100%;
  background-position: left center;
  background-repeat: repeat-x;
  background-size: contain;
  background-image: inherit;
  transition: transform 0.5s ease-out;
}
.project:hover::before {
  transform: translateX(50%);
}
<div class="container">
  <div class="project" style="background-image:url('https://www.dropbox.com/s/fpha4d0uyu71whe/pandora_thumb.png?dl=1')">
  </div>
</div>

设置

出于演示目的,我修改了您的 fiddle。图像比例和相关 CSS 属性相同。那么让我们首先看看我们从我们的设置中得到的东西:

.container {
  max-width: 480px;
  background: orange;
}

.project {
  width: 100%;
  background-image: url("https://i.stack.imgur.com/Wurh4.png");
  background-position: center center;
  background-repeat: no-repeat;
  background-size: contain;
  padding-bottom: 54%;
}
<div class="container">
  <div class="project">
  </div>
</div>

Image width:      504px
Image height:     276px
Container width:  480px
Container height: 259.2px // FireFox 53

由于 background-size: contain 我们的背景图像具有以下尺寸:

BG image height:  259.2px
BG image width:   473.3217...px

高度等于容器高度(这就是 contain 在这种情况下的工作原理)。然后计算宽度如下:(259.2 / 276) * 504.

Difference D:     480px - 473.3217...px = 6.6782...px

这是您可以在上面的代码片段中发现的差距。由于 background-position-x: center,您会在左侧看到 ~3px,在右侧看到另一个 ~3px 的间隙。


背景位置和百分比的工作原理

简而言之:background-position-x: 50% 将背景图像的中心置于容器的中心。所以 background-position-x: 100% 只会将图像的右侧与容器的右侧对齐。

.container {
  width: 700px;
  height: 300px;
  background: orange;
  background-image: url("https://i.stack.imgur.com/Wurh4.png");
  background-position: 90% 50%;
  background-repeat: no-repeat;
}
<div class="container">
</div>

上面计算出的差值D正是background-position-x: 100%中的100%用px表示的。


7100%不是随机的

Difference D:     6.6782...px
Factor F:         480px / D = 71.8749...

要将我们的背景图像完全移出查看范围,我们必须设置 background-position-x: 7174%。现在应该回答问题 1。如果您跳过这里的所有内容,简短的回答是:100% 的值对于 background-position 属性.

具有非常特殊的含义

When I set the padding-bottom to anything over 54%, the transition and everything stops working.

是的,因为这样背景图像的宽度就会大于容器的宽度。