完美全页背景图片

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您的旅程的每个阶段提供云产品。从 $200 免费信用额度 开始!

这篇文章最初发表于 2009 年 8 月 21 日,现已更新,因为它已 _完全修订_。两种原始方法都已删除,现在被四种新方法取代。

这里的目标是在网站上使用背景图片,该图片始终覆盖整个浏览器窗口。让我们对此进行一些具体说明

  • 用图片填充整个页面,没有空白
  • 根据需要缩放图片
  • 保留图片比例(纵横比)
  • 图片居中于页面
  • 不会 _导致_ 滚动条
  • 尽可能地跨浏览器兼容
  • 不是一些像 Flash 这样的花哨把戏

很棒、简单、渐进的 CSS 方法

现在,由于 CSS 中的 background-size 属性,我们可以完全通过 CSS 来做到这一点。我们将使用 html 元素(比 body 更好,因为它始终至少与浏览器窗口的高度相同)。我们为它设置一个固定和居中的背景,然后使用设置为 cover 关键字的 background-size 来调整它的尺寸。

html { 
  background: url(images/bg.jpg) no-repeat center center fixed; 
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
}

适用于

  • Safari 3+
  • Chrome 无论什么+
  • IE 9+
  • Opera 10+(Opera 9.5 支持 background-size 但不支持关键字)
  • Firefox 3.6+(Firefox 4 支持非供应商前缀版本)

更新:感谢评论中的 Goltzman 指出 Adobe Developer Connection 文章,其中包含一些代码,可以使 IE 也执行覆盖背景。

filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='.myBackground.jpg', sizingMethod='scale');
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='myBackground.jpg', sizingMethod='scale')";

但要注意,读者 Pierre Orsander 说他们尝试过这个方法,但页面上的链接出现了一些问题。

更新:Matt Litherland 写信说,任何尝试使用上述 IE 过滤器并遇到滚动条、死链接或其他任何问题(如上面的 Pierre)的人,应该尝试**不要**在 htmlbody 元素上使用它们。而是使用一个固定位置的 div,宽度和高度为 100%。

仅 CSS 技术 #1

再次感谢,像往常一样,感谢 Doug Neiner 提供了这个替代版本。在这里,我们使用内联元素,它可以在任何浏览器中调整大小。我们设置一个 min-height,使其始终垂直填充浏览器窗口,并设置 100% 的 width,使其始终水平填充。我们还设置了图片宽度的 min-width,以便图片永远不会小于它的实际尺寸。

特别聪明的是使用媒体查询来检查浏览器窗口是否小于图片,并使用百分比-left 和负 left margin 的组合来保持它始终居中。

以下是 CSS

img.bg {
  /* Set rules to fill background */
  min-height: 100%;
  min-width: 1024px;
	
  /* Set up proportionate scaling */
  width: 100%;
  height: auto;
	
  /* Set up positioning */
  position: fixed;
  top: 0;
  left: 0;
}

@media screen and (max-width: 1024px) { /* Specific to this particular image */
  img.bg {
    left: 50%;
    margin-left: -512px;   /* 50% */
  }
}

适用于

  • 任何版本的良好浏览器:Safari / Chrome / Opera / Firefox
  • IE 6:坏掉了 - 但如果你使用某种固定定位的垫片,可能可以修复
  • IE 7/8:主要有效,在小尺寸下不会居中,但可以很好地填充屏幕
  • IE 9:有效

查看演示

仅 CSS 技术 #2

处理这个问题的一个相当简单的方法是将一个内联图片放在页面上,将其固定定位到左上角,并赋予它 100% 的 min-widthmin-height,保留它的纵横比。

<img class="bg" src="images/bg.jpg" alt="">
.bg {
  position: fixed; 
  top: 0; 
  left: 0; 
	
  /* Preserve aspet ratio */
  min-width: 100%;
  min-height: 100%;
}

但是,这不会使图片居中,而这是这里一个非常常见的愿望……所以,我们可以通过将图片包裹在一个 div 中来修复它。我们将使该 div 的大小是浏览器窗口的两倍。然后,图片将被放置,仍然保留它的纵横比并覆盖可见的浏览器窗口,以及它的中心。

<div class="bg">
  <img src="images/bg.jpg" alt="">
</div>
.bg {
  position: fixed; 
  top: -50%; 
  left: -50%; 
  width: 200%; 
  height: 200%;
}
.bg img {
  position: absolute; 
  top: 0; 
  left: 0; 
  right: 0; 
  bottom: 0; 
  margin: auto; 
  min-width: 50%;
  min-height: 50%;
}

感谢 Corey Worrell 提出了这个想法。

适用于

  • Safari / Chrome / Firefox(没有测试过很早的版本,但最近的版本都没问题)
  • IE 8+
  • Opera(任何版本)和 IE 都以相同的方式**失败**(定位错误,不知道为什么)
  • Peter VanWylen 写信说,如果你通过 JavaScript 添加图片,则 img 需要具有 width: auto; 和 height: auto; 才能在 IE 8、9 或 10 中起作用。

查看演示

2018 年 1 月更新:试图在 Android 上让它工作?JL García 写信给我说,他需要在 html 元素中添加 height: 100%; 和 overflow: hidden; 才能使其正常工作。完整的代码段是

html {
  background: url(images/bg.jpg) no-repeat center center fixed;
  background-size: cover;
  height: 100%;
  overflow: hidden;
}

我测试了一下,它似乎完全正确。 没有它 / 有它

jQuery 方法

如果我们知道图片(我们要用作背景的内联 )的纵横比是否大于或小于当前浏览器窗口的纵横比,那么整个想法就会变得容易得多(从 CSS 的角度来看)。如果它更低,那么我们可以在图片上设置 _仅_ width 为 100%,并且知道它将填充高度和宽度。如果它更高,我们可以在图片上设置 _仅_ height 为 100%,并且知道它将填充高度和宽度。

我们可以通过 JavaScript 获取这些信息。像往常一样,我喜欢依靠 jQuery。

<img id="bg" src="images/bg.jpg" alt="">
#bg { position: fixed; top: 0; left: 0; }
.bgwidth { width: 100%; }
.bgheight { height: 100%; }
$(window).load(function() {    
  var theWindow = $(window),
  $bg = $("#bg"),
  aspectRatio = $bg.width() / $bg.height();	    			    		
  function resizeBg() {		
    if ( (theWindow.width() / theWindow.height()) < aspectRatio ) {
      $bg
      .removeClass()
      .addClass('bgheight');
    } else {
      $bg
      .removeClass()
      .addClass('bgwidth');
    }					
  }	                   			
  theWindow.resize(resizeBg).trigger("resize");
});

这没有考虑居中,但你绝对可以修改它来做到这一点。感谢 Koen Haarbosch 提出了这个想法。

适用于

  • IE7+(可能可以用固定定位的垫片在 IE6 中使用)
  • 大多数其他桌面浏览器

查看演示

更新(2012 年 6 月):读者 Craig Manley 写信介绍了一种根据屏幕加载适当大小背景图片的技术。也就是说,不要为 iPhone 加载一些巨大的 1900px 宽的背景图片。

首先,你会制作像 1024.jpg1280.jpg1366.jpg 等等的图片。然后,你不会加载图片,而是加载一个垫片。

<img id="bg" style="position: fixed; left: 0; top: 0;" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="">

如果你不喜欢 gif 垫片(我个人认为它还可以,因为它不是“内容”,而是一个背景),你可以加载其中一张真实的图片。这段代码将考虑这种情况。

然后你测试屏幕宽度,并根据它设置图片的 src。下面的代码在调整大小时执行此操作,你可能需要也可能不需要这样做。如果你想,你只需运行一次代码。

(function() {

var win = $(window);

win.resize(function() {
    
  var win_w = win.width(),
  win_h = win.height(),
  $bg = $("#bg");

    // Load narrowest background image based on 
    // viewport width, but never load anything narrower 
    // that what's already loaded if anything.
    var available = [
      1024, 1280, 1366,
      1400, 1680, 1920,
      2560, 3840, 4860
    ];

    var current = $bg.attr('src').match(/([0-9]+)/) ? RegExp.$1 : null;
    
    if (!current || ((current < win_w) && (current < available[available.length - 1]))) {
      
      var chosen = available[available.length - 1];
      
      for (var i=0; i<available.length; i++)="" {="" if="" (available[i]="">= win_w) {
          chosen = available[i];
          break;
        }
      }
      
      // Set the new image
      $bg.attr('src', '/img/bg/' + chosen + '.jpg');
      
      // for testing...
      // console.log('Chosen background: ' + chosen);
      
    }

    // Determine whether width or height should be 100%
    if ((win_w / win_h) < ($bg.width() / $bg.height())) {
      $bg.css({height: '100%', width: 'auto'});
    } else {
      $bg.css({width: '100%', height: 'auto'});
    }
    
  }).resize();
  
})(jQuery)</available.length;>

注意,屏幕宽度不是选择图片大小时唯一可能的好信息。 参见这篇文章

尽情享受

如果你使用这个方法,请随时在下面的评论中留下你使用的技术,以及你是否对其进行过任何修改。看到“现实中”的技巧总是很酷的。

仅仅为了后代起见,这里还有一个名为 table.php 的示例,它使用了曾经是本文一部分的旧技术。它有一些巧妙之处,但并不像上面介绍的两种 CSS 技术那样好。

其他资源