Alternative for background-size:cover in IE7+

by ediblecode   Last Updated June 13, 2019 08:26 AM

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?



Answers 9


Sounds like you need a 'shim' or 'polyfill' like Modernizer: http://modernizr.com/docs/#html5inie

tomByrer
tomByrer
April 13, 2012 14:51 PM

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.

fcalderan
fcalderan
April 16, 2012 13:53 PM

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% */
    }
}
Dean_Wilson
Dean_Wilson
April 16, 2012 23:58 PM

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!

The John Smith
The John Smith
April 17, 2012 15:24 PM

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.

DACrosby
DACrosby
April 20, 2012 04:00 AM

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;
}

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

Liam Newmarch
Liam Newmarch
November 28, 2012 10:26 AM

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.

neil1967
neil1967
August 13, 2013 13:28 PM

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

The following worked for me.

body {
background-size:100%;
}
Ned
Ned
September 19, 2013 00:17 AM

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%);

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/

This logic works in all browsers.

Mohammed Furqan Rahamath M
Mohammed Furqan Rahamath M
June 13, 2019 08:25 AM

Related Questions


Updated March 15, 2019 21:26 PM

Updated June 04, 2015 04:11 AM

Updated October 08, 2018 21:26 PM

Updated April 01, 2017 20:26 PM