简体   繁体   中英

Alternative for background-size:cover in IE7+

I have a background image on the body of my web page. I have used background-size:cover so that the image stretches across the body whilst maintaining the aspect ratio of the image. I would like this to be the same for IE7 + IE8.

I have looked around and seen the following code:

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

But this doesn't preserve the aspect ratio, which is really bad for the website we are aiming at.

Is there any way to do this? Without hitting up jQuery?

What's the reason of not using jQuery? You could load it in conditional comments for IE<8 only, so that for every other modern browser jQuery is not loaded.

Also consider that IE7 has a very low market share (2,52%, April 2012) so it can be acceptable to load ~ 25kb extra for that specific browser if this feature is so important for your site/application.

So, I've found this plugin for jQuery: https://github.com/louisremi/jquery.backgroundSize.js

A jQuery cssHook adding support for "cover" and "contain" to IE6-7-8, in 1.5K

See Github project page for more info.

backgroundSize.js will not actually stretch the bg image in IE7, it seems to just center it at the original size. See their demo and click on 'Check what IE6-7-8 users would normally see.'


@danRhul

I have read that backstretch will work in IE7+

Good luck!

You could just fake a background image with an actual image. It's a bit more HTML editing and certainly not ideal, but since when has handling IE ever been ideal?

<body>
  <img id="mainBG" src="mainBG.jpg" />
  <div id="content">
  [ ... ]

Then style it accordingly

body{
  position:relative;
}
#mainBG{
  width:100%
  position:absolute;
  top:0px;
  left:0px;
}

Should be cross-browser if I'm not mistaken.

I've used the following ( http://css-tricks.com/perfect-full-page-background-image/ ) and it works well in ie7.

HTML:

<body>
    <img class="bg" src="filename">       
</body>   

CSS:

.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% */
    }
}

I know this is now an old question, but I thought I'd share a solution I came up with for anyone else who finds this question on google, like I did.

I was trying to get an image to cover a site's background and came across this question, however none of the solutions worked for me. I came up with this instead:

HTML : move the background image to an <img /> , make it the first thing in your <body> .

<html>
    <body>
        <img class="background" src="kitty.jpg" />
        <div class="content">
            ...

CSS : make the background appear under the content, set it's min-width/height to 100%.

html {
    height: 100%
}

body .background {
    position: absolute;
    z-index: -1;
    min-height: 100%;
    min-width: 100%;
}

It's the min-height and min-width here that does the magic. Do not give the image a width and height in the HTML or CSS, or the aspect ratio will change.

The above will work for IE7 and IE8 . If you would like to support IE6 , you could set a centered image fallback like this:

CSS : If IE6 , don't display the image, use a background image instead.

body {
    _background: url("kitty.jpg") 50% top no-repeat;
}

body .background {
    _display: none;
}

(NB If you don't like the underscore hack to target IE6 , you could use conditionals instead – that's what the HTML5 Boilerplate does.)

Unfortunately, most solutions to this kind of problem either depend on css3 or ignore the native functionality of "cover" that preserves the original aspect ratio of the image. https://github.com/louisremi/background-size-polyfill is supposed to preserve ratio, but I could never get it to work completely when stretching the browser in certain ways (operator error, I'm sure :-) ). To solve this problem, I wrote a jquery script that I've tested on safari, chrome, ff and ie8+. You'll notice that you will have to use an img positioned absolutely instead of css background-image. Just add the bgImg as an id in the tag in html.

CSS:

.container { height: auto; overflow:hidden; position:relative;}
.container #bgImg { position:absolute; z-index:-1;} 

You're image selector will have to be positioned absolutely to get it to sit behind the content. That means that you're parent container has to have position: relative and then overflow: hidden so that whatever overflows from the image (since you're maintaining ratio, some pieces of it inevitable will) is hidden. Be aware also that certain display tags in the parent container will break the hiding of the overflow.

JQUERY:

$(window).load(function () {

    // only do this once and pass as function parameters, because chrome
    // and safari have trouble not only with document.ready but window.resize
    var img = new Image();
    img.src = $("#bgImg").attr('src');
    var $width_orig = img.width;
    var $height_orig = img.height;

    resizeBGImage($width_orig, $height_orig);

    $(window).resize(function () {
        resizeBGImage($width_orig, $height_orig);
    });
});

function resizeBGImage($width_img_orig, $height_img_orig) {
    // get dimensions of container
    var $width_container = $('.container').outerWidth();
    var $height_container = $('.container').outerHeight();

    // calculate original aspect ratio and ratio of the container
    var $imageratio = $width_img_orig / $height_img_orig;
    var $containerratio = $width_container / $height_container;

    var $wdiff = $width_container - $width_img_orig;
    var $hdiff = $height_container - $height_img_orig;

    // original size, so just set to original
    if (($wdiff == 0) && ($hdiff == 0)) {
        $("#bgImg").css('width', $width_img_orig);
        $("#bgImg").css('height', $height_img_orig);
    }
    // if container is smaller along both dimensions than the original image, 
    // set image to container size
    else if (($wdiff < 0) && ($hdiff < 0)) {
        $("#bgImg").css('width', $width_img_orig);
        $("#bgImg").css('height', $height_img_orig+1); // adding one because chrome can't do math
    }
    // if container is wider than long relatiave to original image aspect ratio
    // set width to container width and calculate height 
    else if ($containerratio > $imageratio) {
        $("#bgImg").css('width', $width_container);

        // calculate height using orig aspect ratio and assign to image height 
        $("#bgImg").css('height', (($width_container * $height_img_orig) / $width_img_orig) + 1); // adding one because chrome can't do math
    }
    // else container is taller than long relatiave to original image aspect ratio
    // set height to container height and calculate width
    else {
        // set the image height to container height
        $("#bgImg").css('height', $height_container + 1); // adding one because chrome can't do math

        // calculate width using orig aspect ratio and assign to image width
        $("#bgImg").css('width', (($height_container * $width_img_orig) / $height_img_orig));
    }
    $("#bgImg").css('left', (($width_container - $("#bgImg").width()) / 2).toString() + 'px');
};

Note the use of $(window).load() instead of $(document).ready(). Chrome and safari seem to have issues with the latter since in those browsers, the background image may not be fully loaded when the DOM is. Using $(window).load() ensures all window elements are in place before the script runs.

After much trial and error, the best solution was guessing it!

The following worked for me.

body {
background-size:100%;
}

You have two options to achieve this with just CSS :

  • Use Object-fit: cover . The only problem with this is that it will not work in all browsers
  • If you want cross browser support, you can follow primitive CSS approach:

Position the image inside the container with absolute and then place it right at the centre using the combination:

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

Note: Since transform ONLY works from IE9, you can make use of filters. Here is an answer for this.

Once it is in the centre, you can do,

// For vertical blocks (i.e., where height is greater than width)
height: 100%;
width: auto;

// For Horizontal blocks (i.e., where width is greater than height)
height: auto;
width: 100%;

This makes the image get the effect of Object-fit:cover.


Here is a demonstration of the above logic.

https://jsfiddle.net/furqan_694/s3xLe1gp/

听起来你需要像Modernizer这样的'垫片'或'polyfill': http//modernizr.com/docs/#html5inie

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM