13

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?

ediblecode
  • 11,701
  • 19
  • 68
  • 116
  • 1
    http://css-tricks.com/perfect-full-page-background-image/ – My Head Hurts Apr 16 '12 at 18:15
  • @MyHeadHurts This only works in IE9+ – ediblecode Apr 17 '12 at 11:25
  • 1
    The `CSS-Only Technique #1` works for IE7 and provides a link to a working example. Although the "CSS-Only" part is a little misleading as you add an inline `img` element. As far as I am aware, this will be the only way to do it without "hitting up" JQuery – My Head Hurts Apr 17 '12 at 12:40

9 Answers9

12

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.

Fabrizio Calderan
  • 120,726
  • 26
  • 164
  • 177
  • The reason for not using jQuery, I imagine, is because of the <10% internet users with JS disabled. Probably? The exact numbers seem hard to come by, but this post has a fair number of references. http://stackoverflow.com/questions/9478737/browser-statistics-on-javascript-disabled – DACrosby Apr 20 '12 at 04:10
  • Some thoughts: 1. I think js is necessary here 2. The trick is only for IE (and usually IE comes with js enabled, excluding intranet) 3. Think in terms of progressive enhancement. No JS -> your image will be positioned (in IE) seeing a different effect. – Fabrizio Calderan Apr 20 '12 at 07:25
  • Another reason for not using Jquery is that we might need the same thing for email templates. Most email clients such as Gmail and Outlook (the big ones) will strip out any JS. Even the CSS needs to be old -- Outlook 2010 is still based on IE6 or lower. – PKHunter Aug 21 '13 at 03:43
  • @PKHunter, Outlook 2010 and forward use *Word* to render HTML, not IE6. Which is arguably worse. – Euro Micelli Oct 30 '13 at 21:38
4

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
  • 431
  • 3
  • 10
3

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
  • 11,116
  • 3
  • 39
  • 51
2

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
  • 190
  • 13
  • One issue with your solution is that IE8 and under do not support the @media query `(max-width: 1024px)` that you are using for "centering." That is an issue I ran into with my thoughts I have been pondering for a solution to this. To center it (if it requires such) would seem to require javascript, which danRhul already nixed as being acceptable as an answer. – ScottS Apr 18 '12 at 02:42
  • 1
    Also, since you swiped the code (which in itself is not bad, it shows research), you should have given a link to the source as credit, whether [here](http://css-tricks.com/perfect-full-page-background-image/) or someplace else. – ScottS Apr 18 '12 at 02:58
  • Yeah good point - I was lazy there, I had it somewhere else and didnt have the link handy. EDITED – Dean_Wilson Apr 18 '12 at 05:42
  • If the image is stretched across the whole ``, is there any way the image wouldn't be centered? Aside from adding a negative margin, I suppose. – DACrosby Apr 20 '12 at 04:06
1

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
  • 3,935
  • 3
  • 32
  • 46
1

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

The following worked for me.

body {
background-size:100%;
}
Ned
  • 11
  • 1
  • I had mentioned this in the question. `background-size` doesn't work in IE7, so unfortunately, it doesn't really answer the question. – ediblecode Sep 19 '13 at 08:30
1

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/

Furqan Rahamath
  • 2,034
  • 1
  • 19
  • 29
  • This does not work in IE < 9 (and the question was for IE7) since they don't support transform/translate. https://caniuse.com/#feat=transforms2d – Karl-Johan Sjögren Jun 13 '19 at 08:37
  • @Karl-JohanSjögren Does the added note help? – Furqan Rahamath Jun 13 '19 at 08:44
  • Well your answer stil doesn't answer the actual question since it just refers to another answer that at best points in the right direction for IE7. Also your last sentence with "This logic works in all browsers" is still wrong. – Karl-Johan Sjögren Jun 13 '19 at 11:47
  • True, I have removed the last sentence. Thanks for pointing it out. Regarding my answer, I still want to keep it here as it directs towards an approach that might work. Please correct me if I'm wrong @Karl-JohanSjögren – Furqan Rahamath Jun 13 '19 at 12:00
0

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
  • 257
  • 3
  • 16
-1

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

tomByrer
  • 1,105
  • 12
  • 21