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.