CSS background-size:封面+背景附件:固定剪辑背景图片

时间:2014-02-14 17:55:46

标签: css background-image background-attachment background-size

我有一个包含背景图像的图表列表。如下所示:

<ul>
  <li>
    <figure style="background-image: url(...);"></figure>
  </li>
  <li>
    <figure style="background-image: url(...);"></figure>
  </li>
  <li>
    <figure style="background-image: url(...);"></figure>
  </li>
</ul>

其中每张图片的background-size设置为coverbackground-attachment设置为fixed

figure {
  width: 100%;
  height: 100%;
  background-size: cover;
  background-attachment: fixed;
}

当每个图形占据整个视口时,这样可以正常工作,但如果存在任何类型的偏移,背景图像将被剪切。

据我所知,这是设计(https://developer.mozilla.org/en-US/docs/Web/CSS/background-size#Values)。

我希望图像可以垂直或水平剪辑,但不能同时剪辑,而是以图形本身的大小为中心。

我知道有javascript解决方案,但有没有办法用CSS做到这一点?

以下是一个工作示例:http://codepen.io/Godwin/pen/KepiJ

9 个答案:

答案 0 :(得分:55)

不幸的是,这只是一个固定定位如何在CSS中工作的工件,并且在纯CSS中无法解决它 - 你必须使用Javascript。

发生这种情况的原因是background-attachment: fixedbackground-size: cover的组合。当您指定background-attachment: fixed时,它实际上会导致background-image的行为就像它是position: fixed图像一样,这意味着它已从页面流和定位上下文中取出并变为相对的到视口而不是它是背景图像的元素。

因此,无论何时一起使用这些属性,都会相对于视口的大小计算cover值,而不管元素本身的大小,这就是为什么当元素相同时它按预期工作的原因size作为视口,但在元素小于视口时以意外方式裁剪。

要解决此问题,您基本上需要使用background-attachment: scroll并将事件侦听器绑定到JS中的scroll事件,该事件相对于窗口滚动的距离手动更新background-position为了模拟固定定位,但仍然相对于容器元素而不是视口计算background-size: cover

答案 1 :(得分:22)

有一个jQuery修复此问题:http://jsfiddle.net/QN9cH/1/ 我知道它不是最佳的,但至少它可以工作:)

$(window).scroll(function() {
  var scrolledY = $(window).scrollTop();
  $('#container').css('background-position', 'left ' + ((scrolledY)) + 'px');
});

答案 2 :(得分:2)

background: url(<image>) center top no-repeat fixed;
background-size: auto <width size in %>;

没有真正的解决方案。但是,您可以使图片的大小高度auto而不是cover。并在元素中调整%的宽度,直到它咬住边框。

你看,如果你调整窗口大小,它就不会被剪裁。相反,它将始终保持原始图像大小格式。有了这个,你基本上就可以'缩放&#39;但它并没有覆盖&#39;它了。

答案 3 :(得分:1)

背景尺寸:封面;属性确实是剪切图像以使其填充区域而没有任何空白区域。

background-size:包含;属性决定哪个维度更大,并根据它进行扩展。因此,如果您有100px x 100px块和200x150px的背景图像,则将背景大小设置为包含将缩放图像为100x75px。但是,在这种情况下,如果元素的宽高比与图像的宽高比不同,则会有空格。

您也可以手动控制哪个比例具有优先级,假设您知道图像的宽高比。

因此,如果你知道你的图像总是100x200px,这意味着宽度始终是小尺寸,高度是大尺寸。

现在设置background-size:100%auto;将确保你不会得到空的空间,但你最终会削减。如果将其设置为background-size:auto 100%;它将确保不会发生削波,高度永远不会有空的空间(但宽度会是这样)。

如果您确实需要裁剪并且只是居中图像,请使用background-position:50%;。

答案 4 :(得分:0)

Nick Noordijk的回答让我走上正轨,但我喜欢避免每次滚动事件发生时执行计算的脚本。这是我的版本,仅在页面加载或屏幕尺寸更改时执行计算:

HTML:

<div class="fake-img"></div>

的CSS:

.fake-img {
    display: block;
    height: 280px;  /* set the height here */
    width: 100%;
    background-image: url('http://example.com/path/to/image.jpg');
    background-repeat: no-repeat;
    background-position: center 68px;
    background-size: auto 50%; /* make a "best guess" here as a default */
    background-attachment: fixed;
    position: relative;
}

jQuery的:

$(window).on('resize load orientationchange', function(){
    responsive_calc();
});

var responsive_calc = function(){

    // get the viewport height
    var h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

    // get the element height
    var bannerHeight = $('.fake-img').height();

    // get the integer percentage value difference between them
    var bgHeightPercent = Math.ceil(bannerHeight/h*100);

    // set background-size height to match the element instead of the viewport
    $('.fake-img').css('background-size', 'auto ' + bgHeightPercent + '%');
}

请注意,这实际上只适用于横向&#34;横幅&#34;图像 - 使用background-size: auto nn%在工作中不具有background-size: cover的相同优势,无论您的图像在任何一个方向上都有多余。

答案 5 :(得分:0)

单独排列元素(不适用于全屏元素)的视差效果示例:

HTML:

<div style="background-image: url('/path/to/image.jpg')">Content</div>

的CSS:

#element_to_scroll {
    background-repeat: no-repeat;
    background-size: cover; 
    background-position-x: center; 
    background-position-y: 0;   
}

JS:

$(window).scroll(function() {
    var realImageWidth = 1280;
    var realImageHeight = 1024;
    var viewportBottom = $(window).scrollTop() + $(window).height();
    $('#element_to_scroll').each(function(){
        var scrollAmountPx = realImageHeight/(realImageWidth/$(this).outerWidth())-$(this).outerHeight();
        var elementOffsetFromBottom = viewportBottom-$(this).offset().top;
        var scrollAreaHeight = $(this).outerHeight() + $(window).height();
        if(elementOffsetFromBottom>0 && elementOffsetFromBottom<scrollAreaHeight) {
            var backgroundPositionOffset = Math.ceil(scrollAmountPx/scrollAreaHeight*elementOffsetFromBottom);
            //$(this).css('background-position-y',"-"+backgroundPositionOffset+"px");
            $(this).clearQueue().animate({'background-position-y':"-"+backgroundPositionOffset+"px"},50);
        }
    });
});

答案 6 :(得分:0)

2018年7月更新:此问题现在有1行修复程序

在阅读this article之前,我遇到了同样的问题,这告诉我可以将此行添加到CSS中以使其起作用:

will-change: transform;

成功了!

现在我的CSS看起来像这样:

.myClass{
    position: relative;
    background: hsla(300, 100%, 90%, 0.1);
    overflow: hidden;
    &::before {
        background-image: url(/img/bg.jpg);
        background-size: cover;
        background-size: cover !important;
        -webkit-background-size: cover !important;
        background-repeat: repeat repeat !important;
        background-attachment: scroll !important;//"fixed" is the desired effect, but mobile browsers find it too "expensive" and disabled it, so use "scroll"
        background-position: 30% 50%;
        @media(min-width: $screen-sm-min){
            background-attachment: fixed !important;
            background-position: 30% 20%;
            will-change: transform;
        }//768
        content: "";
        display: block;
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        opacity: 0.1;
    }
}

它在Windows Chrome,Edge和Safari上对我有用。但不是Firefox。

答案 7 :(得分:0)

另一种非常简单的解决方案是使用vwvh单位(在大多数情况下,如果您不知道,它们具有totally passable browser support)。例如,不要执行background-size: cover,而是执行background-size: auto 100vh

如果您不熟悉vwvh,它们就是视口单位,它们对应于视口宽度和视口高度。这些值对应于视口高度或宽度的百分比。例如,50vw表示视口宽度的50%。

出于我们的目的,我们可以简单地告诉背景是视口高度的100%。

Here's a fiddle.

如果您需要适应不同的宽高比,则可以利用aspect-ratio @media rules

答案 8 :(得分:-4)

我做了一个带有自适应背景图片的版本。

1:CMD VALUE: /system/bin/netstat -a | grep http

http://jsfiddle.net/onigetoc/grpku1gk/