Stretch and scale CSS background

927,742

Solution 1

For modern browsers, you can accomplish this by using background-size:

body {
    background-image: url(bg.jpg);
    background-size: cover;
}

cover means stretching the image either vertically or horizontally so it never tiles/repeats.

That would work for Safari 3 (or later), Chrome, Opera 10+, Firefox 3.6+, and Internet Explorer 9 (or later).

For it to work with lower verions of Internet Explorer, try these CSS:

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

Solution 2

Use the CSS 3 property background-size:

#my_container {
    background-size: 100% auto; /* width and height, can be %, px or whatever. */
}

This is available for modern browsers, since 2012.

Solution 3

Scaling an image with CSS is not quite possible, but a similar effect can be achieved in the following manner, though.

Use this markup:

<div id="background">
    <img src="img.jpg" class="stretch" alt="" />
</div>

with the following CSS:

#background {
    width: 100%; 
    height: 100%; 
    position: absolute; 
    left: 0px; 
    top: 0px; 
    z-index: 0;
}
.stretch {
    width:100%;
    height:100%;
}

and you should be done!

In order to scale the image to be "full bleed" and maintain the aspect ratio, you can do this instead:

.stretch { min-width:100%; min-height:100%; width:auto; height:auto; }

It works out quite nicely! If one dimension is cropped, however, it will be cropped on only one side of the image, rather than being evenly cropped on both sides (and centered). I've tested it in Firefox, Webkit, and Internet Explorer 8.

Solution 4

Use the background-size attribute in CSS3:

.class {
     background-image: url(bg.gif);
     background-size: 100%;
}

EDIT: Modernizr supports detection of background-size support. You can use a JavaScript workaround written to work however you need it and load it dynamically when there is no support. This will keep the code maintainable without resorting to intrusive CSS hacks for certain browsers.

Personally I use a script to deal with it using jQuery, its an adaption of imgsizer. As most designs I do now use width %'s for fluid layouts across devices there is a slight adaptation to one of the loops (accounting for sizes that aren't always 100%):

for (var i = 0; i < images.length; i++) {
    var image = images[i],
        width = String(image.currentStyle.width);
    if (width.indexOf('%') == -1) {
        continue;
    }
    image.origWidth = image.offsetWidth;
    image.origHeight = image.offsetHeight;
    imgCache.push(image);
    c.ieAlpha(image);
    image.style.width = width;
}

EDIT: You may also be interested in jQuery CSS3 Finaliz[s]e.

Solution 5

Try the article background-size. If you use all of the following, it will work in most browsers except Internet Explorer.

.foo {
    background-image: url(bg-image.png);
    -moz-background-size: 100% 100%;
    -o-background-size: 100% 100%;
    -webkit-background-size: 100% 100%; 
    background-size: 100% 100%;
} 
Share:
927,742
Lawrence Dol
Author by

Lawrence Dol

I have been writing code since I was 12 - I started with BASIC on a Commodore VIC-20. First computer I owned was a Sinclair ZX-81 on which I progressed to programming Z80 assembler by the time I was 13. I consider programming to be a lifetime learning experience. In my early professional years there was Pascal and COBOL and in the 90's a fair amount of iSeries CLP and RPG. My current professional experience includes extensive programming in C, Java and JavaScript. The former two languages were primarily in the networking and communications arena, while more recently doing JavaScript (with HTML5 and CSS) for web and mobile applications as well as creating services and the Java backend support (full stack). My programming hobby activities are mostly in Java and JavaScript, but I enjoy dabbling with a variety of procedural, OOP and functional languages and the many hybrids thereof.

Updated on November 24, 2020

Comments

  • Lawrence Dol
    Lawrence Dol over 2 years

    Is there a way to get a background in CSS to stretch or scale to fill its container?

  • Lawrence Dol
    Lawrence Dol over 14 years
    Stretch=Change x and y dimensions independently changing the aspect ration of the image, Scale=change x and y dimensions proportionately maintaining the aspect ratio of the image.
  • BenAlabaster
    BenAlabaster over 14 years
    @SoftwareMonkey: As a background then no, you can't change the stretch and scale in the true sense of the terms in straight CSS. You have to use various CSS tricks to give the illusion that this is what's happening as I've described.
  • Mindey I.
    Mindey I. over 13 years
    This works well...but was looking for something a little more robust (probably with javascript) that also centered it and adjusted based on if the picture was landscape or portrait. If anyone has a solution in that vein would love a link...thanks!
  • Mindey I.
    Mindey I. over 13 years
    In case anyone else is interested, this seemed to work well: buildinternet.com/project/supersized
  • Ronald
    Ronald over 13 years
    Horizontal centering can be done with margin: 0 auto on .stretch. By only setting the width or height, the aspect ratio stays the same. Try using max-width and max-height to limit the zoom-factor...
  • jensgram
    jensgram over 12 years
    Great article available at A List Apart: Supersize that Background, Please!
  • Admin
    Admin over 12 years
    To Clement: What you suggest for filters for previous IE:s work only partly. It scales the picture width ok but the height scaling goes wrong by not restricting it to anything. The higher the page so is the background picture.. =( I tried this on IE8. And also, could it be in anyway possible use these 'cover' commands and somehow make this compatible with mobiles like iphone? I know there is the viewport problem but could it be possibke to scale the viewport to whole screen in a way that background is scaled here?? Thanks for responses!
  • Clement
    Clement about 12 years
    The IE-specific filters are not ideal solutions so feel free to condition for IE with CSS alternatives. I personally use the CSS3 "cover" on my own site and it works fine on iOS devices, just be sure to define the device-width.
  • Potherca
    Potherca about 12 years
    -1 I don't think this answer is very relevant... and it doesn't offer a solution of any kind.
  • Eran Galperin
    Eran Galperin about 12 years
    @Potherca this answer was correct at the time (almost 3 years ago).
  • Eran Galperin
    Eran Galperin about 12 years
    There is a reason the date is shown. It should be kept for historical references. Are you going over all the old answers on the site and downvoting them? the answer is still correct even if more information has been added since then. Also note that other answers here basically state the same (and some are indeed incorrect - they state it's impossible). I get the feeling you picked on this one since it has some votes.
  • Pavel Vlasov
    Pavel Vlasov almost 12 years
    Thank you! This differs from "background-size: cover"
  • Admin
    Admin almost 12 years
    This doesn't work for me in ie8/ie9, but works in ie6/ie7 (and of course all other browsers). In ie8/ie9, the image only shows up for about 3/4 of the div. Anybody have the same issue?
  • Leimi
    Leimi over 11 years
    For ie7, setting .stretch { height: auto } worked in my case whereas height:100% didn't. Otherwise great solution thanks!
  • Potherca
    Potherca over 11 years
    No, I picked on this one since all it does is say "Computer say no" even though there are several solutions to this problem even back in 2008 ;-)
  • Don Cote
    Don Cote over 11 years
    this stretched for me on the ipad, but didn't scale. thx for posting.
  • beingalex
    beingalex about 11 years
    This is great for making it the background shrink too. Thanks!
  • Chris Moschini
    Chris Moschini about 11 years
    Just to emphasize, Modernizr does NOT enable support for background-size in browsers that don't natively support it. It just has a convenient cross-browser test for it. It's up to you to fake it when the test returns false.
  • Glenn Maynard
    Glenn Maynard almost 11 years
    A flaw with SO: there's no way to mark answers which are no longer correct, leading to people like @Ullas being led astray. It's easy to scale backgrounds in all modern browsers. developer.mozilla.org/en/CSS/background-size
  • Metalshark
    Metalshark almost 11 years
    It's not really a flaw with SO if the original author of the answer chooses not to retract/improve their answer when it no longer applies. A moderator or suitably privileged (and trusted) individual should take such action instead. Feel free to take up the matter in meta.stackoverflow.com as I will not discuss the matter further here.
  • Lawrence Dol
    Lawrence Dol over 10 years
    Nick, we generally ask that you provide the salient parts in your answer, and supply an external link only for further detail - this helps answers remain useful in the event of link-rot.
  • nickff
    nickff over 10 years
    My Bad. Generally speaking, you add backstretch to the <head> of your document then initialize like so: $(".your-element").backstretch("path/to/image.jpg");
  • Louis-Rémi
    Louis-Rémi over 10 years
    To preserve the aspect ratio of the image you should use "background-size: cover;" or "background-size: contain;". I've built a polyfill that implements those values in IE8: github.com/louisremi/background-size-polyfill
  • neoswf
    neoswf over 10 years
    Cover doesn`t stretch the bg. 100% 100% yes.
  • ErocM
    ErocM over 10 years
    I know this is a year old but I have to (laugh and) agree with the 'decent browsers' part. Check all of your browsers but I've had more issues with IE than any of them.
  • FarFigNewton
    FarFigNewton over 10 years
    I had to set background-size: 100% 100%; to get the desired effect I was going for, if that helps anyone else.
  • ceving
    ceving about 10 years
    @Louis-Rémi How to center in both directions, when using "cover"?
  • Niels Keurentjes
    Niels Keurentjes about 10 years
    @ceving add background-position:50% 50% - it's then used as the origin.
  • Vilx-
    Vilx- almost 10 years
    @Blowsie - Cute. Check the answer date. The browser landscape has changed a bit in the last 5 years.
  • mohas
    mohas over 9 years
    explanation of cover and contain on MDN
  • Admin
    Admin about 9 years
    guanome thanks, that solved my problem. cover and contain did not work in my scenario.
  • gman
    gman over 8 years
    this doesn't actually work. The question is to fill the container which means we want it to stretch so it doesn't repeat. This answer on the other hand will repeat in the height direction if the height doesn't cover the area. "Stretch to fill" means stretch however you have to so it doesn't repeat. The correct answer is "cover" from below. That actually handles the case that this doesn't.
  • PKHunter
    PKHunter over 6 years
    How's this better or different than just "background-size: cover"?
  • Laurie Stearn
    Laurie Stearn almost 6 years
    That's a pity, if say for example compiling chms for old and new machines. But to get this and the accepted answer working for both using something like @media and jqery won't look very pretty at all!
  • Blowsie
    Blowsie almost 6 years
    @PKHunter , im not sure exactly what you are reffering to. This is using background-size: cover except with browser prefixeds and a IE solution
  • Mr. Noddy
    Mr. Noddy over 5 years
    This solutions worked best for me where I do not wanted to stretch the image either horizontally or vertically more than it's actual resolution. Thanks..!!
  • Mentalist
    Mentalist about 4 years
    If the background image is an SVG, it is also necessary to specify preserveAspectRatio="none" within the SVG. More info about this here. Demo here.
  • Mike
    Mike over 3 years
    NB: As of Chromium 78.0.3904.97, it is not possible to scale svg images independently along each axis. You may have to scale it up and convert it to a raster image.
  • Siraj Ahmed
    Siraj Ahmed over 3 years
    you can use background-size: cover; background-attachment: fixed; you can scale it
  • Michał Perłakowski
    Michał Perłakowski almost 2 years
    @Mike It works if you add preserveAspectRatio="none" to the SVG image.