固定位置的背景图像在div内部

12
我想使div的背景固定,这样切换div会产生像手机屏幕上切换图片的效果。这是一个更糟糕的版本,类似于这个链接: https://www.android.com/versions/nougat-7-0/
用这种方式尝试中:链接

.main {
  min-height: 1000px;
}

.col1 {
  width: 29.9%;
  min-height: 800px;
  display: inline-block;
  float: left;
}

.col2 {
  width: 70%;
  min-height: 800px;
  display: inline-block;
}

.row1 .col1 {
  background: rgba(238, 238, 34, 0.3) url("https://icons.iconarchive.com/icons/graphicloads/100-flat-2/256/24-hours-phone-icon.png") !important;
  background-position: left !important;
  background-repeat: no-repeat !important;
  background-size: contain !important;
  background-attachment: fixed !important;
}

.row2 .col1 {
  background: rgba(238, 238, 34, 0.3) url("https://icons.iconarchive.com/icons/graphicloads/100-flat-2/256/abs-icon.png") !important;
  background-position: left !important;
  background-repeat: no-repeat !important;
  background-size: contain !important;
  background-attachment: fixed !important;
}

.row3 .col1 {
  background: rgba(238, 238, 34, 0.3) url("https://icons.iconarchive.com/icons/graphicloads/100-flat-2/256/arrow-down-icon.png") !important;
  background-position: left !important;
  background-repeat: no-repeat !important;
  background-size: contain !important;
  background-attachment: fixed !important;
}
<div class="main">
  <div class="row1">
    <div class="col1">
      Col1
    </div>
    <div class="col2">
      Col2
    </div>
  </div>
  <div class="row2">
    <div class="col1">
      Col1
    </div>
    <div class="col2">
      Col2
    </div>
  </div>
  <div class="row3">
    <div class="col1">
      Col1
    </div>
    <div class="col2">
      Col2
    </div>
  </div>
</div>

但是,由于图片始终比div大,并且不在我需要的div内部,所以没有运气,而且更麻烦的是,当浏览器大小改变时,背景位置也会改变。 我知道这是因为背景附件被固定,因此它看起来像一个整个视口,而不仅仅是一个div,但是否有任何解决方法可以实现这一点?因此,目标是使背景图像在母div中心位置上得到很好的修饰,但在滚动和切换效果时保持固定位置。 更改浏览器视口时,图片始终以相同的大小位于母div的中心位置。
我知道有关"scroll magic"的信息,但我只想要通过CSS或最少量的JS代码获得更“自然”的东西。
3个回答

5
很遗憾,这只是CSS中固定定位的工作原理所致,在纯CSS中无法避免 - 必须使用Javascript。
这种情况发生的原因是由于background-attachment: fixed和background-size: cover的组合。当您指定background-attachment: fixed时,它实际上会导致background-image表现得像一个position: fixed图像,这意味着它被取出页面流和定位上下文,并相对于视口而不是其作为背景图像的元素而言。
要解决这个问题,基本上需要使用background-attachment: scroll并在JS中绑定一个事件监听器来手动更新背景位置,使其相对于滚动窗口的滚动距离进行模拟固定定位,但仍然根据容器元素而不是视口计算background-size: cover。

1
+1 for JS滚动选项,这可能是一个解决方案,但如果有人知道更自然的东西,那就更好了。绑定滚动可能对移动设备等造成痛苦,也不是最自然的事情。 - Danijel
是的,确切地说,我们还可以在移动设备和桌面上实现更好的视差效果。您还可以控制背景中对象的速度。 - Anmol Sandal
好的,如果没有人从CSS 3中提出真正花哨的东西,那么可能会尝试使用JS和滚动条。 - Danijel

2

经过一些尝试,我得出了这个解决方案,但它是一个JS解决方案,如果有人能用纯CSS解决,我会非常高兴。

Fiddle链接:https://jsfiddle.net/w4hz4cqf/31/

稍微修改了CSS代码:

    .main
    {
      min-height: 1000px;
      width: 500px;
      margin: 0 auto;

    }

    .col1
    {
      width: 150px;
      min-height: 800px;
      display: inline-block;
      float: left;
    }

    .col2
    {
      width: 70%;
      min-height: 800px;
      display: inline-block;
    }

    .row1 .col1
    {
      background: rgba(238,238,34,0.3) url("https://icons.iconarchive.com/icons/graphicloads/100-flat-2/256/24-hours-phone-icon.png") !important;
        //background-position: left !important;
        background-repeat: no-repeat !important;
        background-size: 100px 100px !important;
        background-attachment: fixed !important;
    }

    .row2 .col1
    {
        background: rgba(238,238,34,0.3) url("https://icons.iconarchive.com/icons/graphicloads/100-flat-2/256/abs-icon.png") !important;
        background-position: left !important;
        background-repeat: no-repeat !important;
        background-size: 100px 100px !important;
        background-attachment: fixed !important;
    }

    .row3 .col1
    {
        background: rgba(238,238,34,0.3) url("https://icons.iconarchive.com/icons/graphicloads/100-flat-2/256/arrow-down-icon.png") !important;
        background-position: left !important;
        background-repeat: no-repeat !important;
        background-size: 100px 100px !important;
        background-attachment: fixed !important;
    }

添加了JS代码:

    jQuery(document).ready(function(){
      backgroundImageSize = 100;

      elem = jQuery(".row1 .col1, .row2 .col1, .row3 .col1"); 
      for(ind = 0; ind < 3; ind++) {
        elem[ind].getBoundingClientRect();

          elem[ind].style.setProperty('background-position', (elem[ind].getBoundingClientRect().left + jQuery(".col1").width() / 2 - (backgroundImageSize/2))+'px center', 'important');
      }

      var width = $(window).width();
      $(window).on('resize', function(){
         if($(this).width() != width){
            width = $(this).width();
            elem = jQuery(".row1 .col1, .row2 .col1, .row3 .col1"); 

            for(ind = 0; ind < 3; ind++) {
              elem[ind].getBoundingClientRect();
              elem[ind].style.setProperty('background-position', (elem[ind].getBoundingClientRect().left + jQuery(".col1").width() / 2 - (backgroundImageSize/2))+'px center', 'important');
            }
         }
      });
    });

是的,JS代码并不完美,只是一个概念验证 :) - Danijel

0

试试这个

background-size: 29.9% 100% !important;

小提琴


不错的想法,但问题仍然存在:图像正在改变其大小,可以通过将背景大小设置为px来解决,但是图像仍然对齐到左侧视口,因此它不在中心。 - Danijel
1
这里宽度也可能会有所不同,因此我们无法给出具体的宽度。虽然这是一个很好的想法。 - Anmol Sandal
仍然不行,图像现在正在改变其大小,图像必须完全包含在 div 中。 - Danijel
@xDan 图片不能被裁剪吗? - Shadow Fiend
我不知道这个链接是否是正确的,如果不是,那我就不知道了,哈哈... - Shadow Fiend
我更新了fiddle,只是为了更好地了解问题:https://jsfiddle.net/w4hz4cqf/29/ - Danijel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接