935

I want that my background image stretch and scale depending on the browser viewport size.

I've seen some questions on Stack Overflow that do the job, like Stretch and scale CSS background for example. It works well, but I want to place the image using background, not with an img tag.

In that one an img tag is placed, and then with CSS we tribute to the img tag.

width:100%; height:100%;

It works, but that question is a bit old, and states that in CSS 3 resizing a background image will work pretty well. I've tried this example the first one, but it didn't work out for me.

Is there a good method to do it with the background-image declaration?

Community
  • 1
  • 1
Fábio Antunes
  • 16,984
  • 18
  • 75
  • 96
  • 137
    background-size: 100% 100%; – Andreas L. Aug 30 '14 at 11:41
  • 9
    Maybe this demo can be helpful: http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size – Davide Jan 07 '15 at 18:48
  • 1
    Possible duplicate of [CSS background image to fit width, height should auto-scale in proportion](http://stackoverflow.com/questions/9262861/css-background-image-to-fit-width-height-should-auto-scale-in-proportion) – Alex Angas Mar 01 '16 at 00:57
  • You should clarify whether you want the aspect ratio to change to scale or just scale on either height or width and let the other dimension maintain that aspect ratio. – Joe C Jan 26 '20 at 21:56

22 Answers22

1143

CSS3 has a nice little attribute called background-size:cover.

This scales the image so that the background area is completely covered by the background image while maintaining the aspect ratio. The entire area will be covered. However, part of the image may not be visible if the width/height of the resized image is too large.

TiyebM
  • 2,684
  • 3
  • 40
  • 66
Vashishtha Jogi
  • 12,120
  • 2
  • 19
  • 20
  • 30
    Cover crops the image if the aspect ratio doesn't match, so it's not a good general solution. – mahemoff Jun 21 '13 at 14:47
  • 1
    in case you you want it to work in IE browsers - https://github.com/louisremi/background-size-polyfill – Wreeecks Aug 26 '14 at 02:20
  • 12
    It doesn't seem to work on Firefox. However, `background-size: 100vw 100vh;`does the trick nicely. – Yannick Mauray Jan 28 '18 at 10:02
  • 9
    @YannickMauray try: `background-size: cover; -ms-background-size: cover; -o-background-size: cover; -moz-background-size: cover; -webkit-background-size: cover; ` – Amit Kumar Khare Feb 13 '18 at 13:05
  • 7
    If you want this, but only for the horizontal axis, use this: `background-size: 100% auto;` https://stackoverflow.com/questions/41025630/css-background-image-stretch-horizontally-and-repeat-vertically – antoineMoPa Apr 19 '18 at 17:42
  • Aside of using `background-size:cover`... Don't forget to use services like ImageBoss to generate your images responsively. It would reduce your load time/page speed considerably. – Igor Escobar May 24 '18 at 21:38
  • As you mentioned the my image is getting cropped when i use background-size: cover, what would you suggest I do? – Umakanth Pendyala Jul 13 '20 at 12:39
476

You could use the CSS3 property to do it quite nicely. It resizes to ratio so no image distortion (although it does upscale small images). Just note, it's not implemented in all browsers yet.

background-size: 100%;
Matt Burgess
  • 5,028
  • 2
  • 16
  • 15
  • 23
    @nXqd That pretty much is the full code! Create a container with a `background-image` and include the property above. As mentioned, browser support is not good yet and there are browser specific versions of this ie. `-webkit-background-size` etc. See [W3C CSS3 Module: background-size](http://www.w3.org/TR/2002/WD-css3-background-20020802/#background-size) and [css3.info: background-size](http://www.css3.info/preview/background-size/) – MrWhite Jun 20 '11 at 07:28
  • 19
    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: http://github.com/louisremi/background-size-polyfill – Louis-Rémi Dec 05 '12 at 09:56
  • 4
    It's also advisable to add `auto` to preserve aspect ratio. – Chibueze Opata Dec 09 '12 at 12:53
  • 1
    For those like me wondering why this didn't work for their svg file, add this attribute to the outermost `svg` tag: `preserveAspectRatio="none"` – Daniel Kaplan Oct 19 '22 at 19:09
192

Using the code I mentioned...

HTML

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

CSS

#background {
    width: 100%; 
    height: 100%; 
    position: fixed; 
    left: 0px; 
    top: 0px; 
    z-index: -1; /* Ensure div tag stays behind content; -999 might work, too. */
}

.stretch {
    width:100%;
    height:100%;
}

That produces the desired effect: only the content will scroll, not the background.

The background image resizes to the browser viewport for any screen size. When the content doesn't fit the browser viewport, and the user needs to scroll the page, the background image remains fixed in the viewport while the content scrolls.

With CSS 3 it seems this would be a lot easier.

Community
  • 1
  • 1
Fábio Antunes
  • 16,984
  • 18
  • 75
  • 96
  • 15
    But this is not background image. You can only do this to a block, but not a inline element such as a input[type=text]. Or am I wrong? – deerchao Dec 07 '11 at 07:09
  • 14
    no need for the class="stretch", just use #background img {} as identifier in the css – BerggreenDK Aug 24 '12 at 08:04
  • z-index: -1; keeps your image in the background. If you desire to show your image in the foreground, you can either increase the z-index value or remove that index. – gokhanakkurt Oct 07 '13 at 16:09
  • The issue I am having is with IE8. The background image of a DIV stretches full but in IE8 the images goes outside the DIV hence not being able to see the full image. It gets cropped out. Here is my question: http://stackoverflow.com/questions/22331179/why-the-background-image-does-not-fill-the-entire-div – Si8 Mar 11 '14 at 17:25
  • 1
    The obvious mistake people do is to put the background image in the css (ie by `background : url("example.png");`) and then use the css attribute `background-size:100%;` beneath it to hopefully scale the image to screen width. This will not work, Will it? If you wish to put a background image for the body then an image attribute should be added to the body tag like ``. Then use css `background-size:100%;` to scale it. – sjsam Jan 07 '15 at 08:52
172

CSS:

html,body {
    background: url(images/bg.jpg) no-repeat center center fixed;
    -webkit-background-size: cover; /* For WebKit*/
    -moz-background-size: cover;    /* Mozilla*/
    -o-background-size: cover;      /* Opera*/
    background-size: cover;         /* Generic*/
}
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
63
background-size: 100% 100%; 

stretches the background to fill the entire element on both axes.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
yeahdixon
  • 6,647
  • 1
  • 41
  • 43
43

The following CSS part should stretch the image with all browsers.

I do this dynamically for each page. Therefore I use PHP to generate its own HTML tag for each page. All the pictures are in the 'image' folder and end with 'Bg.jpg'.

<html style="
      background: url(images/'.$pic.'Bg.jpg) no-repeat center center fixed;
      -webkit-background-size: cover;
      -moz-background-size: cover;
      -o-background-size: cover;
      background-size: cover;
      filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'images/'.$pic.'Bg.jpg\',     sizingMethod=\'scale\');
      -ms-filter: \"progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'images/'.$pic.'Bg.jpg\', sizingMethod=\'scale\')\
";>

If you have only one background picture for all pages then you may remove the $pic variable, remove escaping back-slashes, adjust paths and place this code in your CSS file.

html{
    background: url(images/homeBg.jpg) no-repeat center center fixed;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
    filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/homeBg.jpg',     sizingMethod='scale');
    -ms-filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/homeBg', sizingMethod='scale');
}

This was tested with Internet Explorer 9, Chrome 21, and Firefox 14.

Popnoodles
  • 28,090
  • 2
  • 45
  • 53
Thorsten Niehues
  • 13,712
  • 22
  • 78
  • 113
  • 2
    Your example doesn't work in sense of backwards compatibility, because you simply forgot about the leading '-' of vendor prefixes. It must be `-webkit-background-size`, `-moz-background-size` and so on. See https://developer.mozilla.org/en-US/docs/CSS/background-size#Browser_compatibility Or you go for including it future-proof in shorthand property like `background: url(img/bg-home.jpg) no-repeat center center / cover fixed;` – Volker E. May 08 '13 at 04:26
20

Use this CSS:

background: url('img.png') no-repeat; 
background-size: 100%;
Rory Harvey
  • 2,579
  • 2
  • 22
  • 27
18

You can actually achieve the same effect as a background image with the img tag. You just have to set its z-index lower than everything else, set position:absolute and use a transparent background for every box in the foreground.

Kim Stebel
  • 41,826
  • 12
  • 125
  • 142
  • Thats what i saw in others SO questions, and works, but since CSS3 as come out, i thought that now was a better way to to it. – Fábio Antunes Jul 19 '09 at 19:07
  • 4
    There might be and taking into account developments in browser usage, you might be able to use them commercially in only...10 year? – Kim Stebel Jul 20 '09 at 03:48
  • Being CSS3, there is nothing wrong with using a property that the most modern browsers see and giving a minimum standard to unsupported browsers. Here, for example, you might be able to use a boring but acceptable tiled background for – Dan Blows May 10 '11 at 02:06
  • Just found this other post which references the use of the proprietary MS AlphaImageLoader: http://stackoverflow.com/questions/2991623/make-background-size-work-in-ie – gxc Sep 28 '11 at 19:31
15

You can add this class into your CSS file.

.stretch {
    background: url(images/bg.jpg) no-repeat center center fixed;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
}

It works in:

  • Safari 3 or later
  • Chrome Whatever or later
  • Internet Explorer 9 or later
  • Opera 10 or later (Opera 9.5 supported background-size, but not the keywords)
  • Firefox 3.6 or later (Firefox 4 supports non-vendor prefixed version)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Arunraj S
  • 758
  • 7
  • 26
14

It is explained by CSS tricks: Perfect Full Page Background Image

Demo: https://css-tricks.com/examples/FullPageBackgroundImage/progressive.php

Code:

body {
  background: url(images/myBackground.jpg) no-repeat center center fixed;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Aamer Shahzad
  • 2,617
  • 1
  • 27
  • 25
  • based on above answer, I have seen background attachment fix does not work on mobile devices and microsoft edge. The perfect solution to make background stretch and fix on all devices and browsers I recommend http://www.jquery-backstretch.com/ – Aamer Shahzad Nov 02 '18 at 08:47
10

In order to scale your images appropriately based on the container size, use the following:

background-size: contain;
background-repeat: no-repeat;
Roman Snitko
  • 3,655
  • 24
  • 29
justinpees
  • 420
  • 5
  • 20
9

I use this, and it works with all browsers:

<html>
    <head>
        <title>Stretched Background Image</title>
        <style type="text/css">
            /* Remove margins from the 'html' and 'body' tags, and ensure the page takes up full screen height. */
            html, body {height:100%; margin:0; padding:0;}

            /* Set the position and dimensions of the background image. */
            #page-background {position:fixed; top:0; left:0; width:100%; height:100%;}

            /* Specify the position and layering for the content that needs to appear in front of the background image. Must have a higher z-index value than the background image. Also add some padding to compensate for removing the margin from the 'html' and 'body' tags. */
            #content {position:relative; z-index:1; padding:10px;}
        </style>
        <!-- The above code doesn't work in Internet Explorer 6. To address this, we use a conditional comment to specify an alternative style sheet for IE 6. -->
        <!--[if IE 6]>
        <style type="text/css">
            html {overflow-y:hidden;}
            body {overflow-y:auto;}
            #page-background {position:absolute; z-index:-1;}
            #content {position:static;padding:10px;}
        </style>
        <![endif]-->
    </head>
    <body>
        <div id="page-background"><img src="http://www.quackit.com/pix/milford_sound/milford_sound.jpg" width="100%" height="100%" alt="Smile"></div>
        <div id="content">
            <h2>Stretch that Background Image!</h2>
            <p>This text appears in front of the background image. This is because we've used CSS to layer the content in front of the background image. The background image will stretch to fit your browser window. You can see the image grow and shrink as you resize your browser.</p>
            <p>Go on, try it - resize your browser!</p>
        </div>
    </body>
</html>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mahdi jokar
  • 1,267
  • 6
  • 30
  • 50
8

Thanks!

But then it was not working for the Google Chrome and Safari browsers (stretching worked, but the hight of the pictures was only 2 mm!), until someone told me what lacks:

Try to set height:auto;min-height:100%;

So change that for your height:100%; line, gives:

#### #background {
    width: 100%; 
    height: 100%; 
    position: fixed; 
    left: 0px; 
    top: 0px; 
    z-index: -1;
}

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

Just before that newly added code I have this in my Drupal Tendu themes style.css:

html, body{height:100%;}

#page{background:#ffffff; height:auto !important;height:100%;min-height:100%;position:relative;}

Then I have to make a new block within Drupal with the picture while adding class=stretch:

< img alt="" class="stretch" src="pic.url" />

Just copying a picture with the editor in that Drupal block doesn't work; one has to change the editor to non-formatted text.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Cybr
  • 81
  • 1
  • 1
8

I wanted to center and scale a background image, without stretching it to the entire page, and I wanted the aspect ratio to be maintained. This worked for me, thanks to the variations suggested in other answers:

INLINE IMAGE: ------------------------

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

CSS ----------------------------------

html {
    height:100%;
}

#background {
    text-align: center;
    width: 100%; 
    height: 100%; 
    position: fixed;
    left: 0px; 
    top: 0px; 
    z-index: -1;
}

.stretch {
    margin: auto;
    height:100%;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
AnnieDee
  • 91
  • 1
  • 1
8

I agree with the image in absolute div with 100% width and height. Make sure you set 100% width and height for the body in the CSS and set margins and padding to zero. Another issue you will find with this method is that when selecting text, the selection area can sometimes encompass the background image, which has the unfortunate effect of making the full page have the selected state. You can get round this by using the user-select:none CSS rule, like so:

<html>
    <head>
        <style type="text/css">

            html,body {
                height: 100%;
                width: 100%
                margin: none;
                padding: none;
            }

            #background {
                width: 100%;
                height: 100%;
                position: fixed;
                left: 0px;
                top: 0px;
                z-index: -99999;
                -webkit-user-select: none;
                -khtml-user-select: none;
                -moz-user-select: none;
                -o-user-select: none;
                user-select: none;
            }

            #background img {
                width: 100%;
                height: 100%;
            }

            #main{ z-index:10;}
        </style>
    </head>
    <body>
        <div id="main">
            content here
        </div>
        <div id="background"><img src="bg.jpg"></div>
    </body>
</html>

Again, Internet Explorer is the bad guy here, because it doesn't recognise the user-select option - not even Internet Explorer 10 preview supports it, so you have the option of either using JavaScript to prevent background image selection (for example, http://www.felgall.com/jstip35.htm ) or using CSS 3 background-stretch method.

Also, for SEO I would put the background image at the bottom of the page, but if the background image takes too long to load (that is, with a white background initially), you could move to the top of the page.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Myke Black
  • 1,299
  • 15
  • 15
5

I used a combination of the background-X CSS properties to achieve the ideal scaling background image.

background-size: cover;
background-repeat: no-repeat;
background-position: center;
background-attachment: fixed;

This makes the background always cover the entire browser window and remains centered when scaling.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ryan Den-Kaat
  • 118
  • 1
  • 5
5

The following worked for me.

.back-ground {
   background-image: url("../assets/background.png");
   background-size: 100vw 100vh;
}

that worked to cover the entire background on different dimensions

tony2tones
  • 1,422
  • 1
  • 18
  • 19
4

Use the Backstretch plugin. One could even have several images slide. It also works within containers. This way for example one could have only a portion of the background been covered with an background image.

Since even I could get it to work proves it to be an easy to use plugin :).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Daniel
  • 93
  • 7
3

If you want to have the content centered horizontally, use a combination like this:

background-repeat: no-repeat;
background-size: cover;
background-position: center;

This will look beautiful.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Samuel Ramzan
  • 1,770
  • 1
  • 15
  • 24
1

You can use the border-image : yourimage property to scale the image up to the border. Even if you give the background-image, the border image will be drawn over it.

The border-image property is very useful if your style sheet is implemented somewhere which doesn't support CSS 3. If you are using Google Chrome or Firefox, then I recommend the background-size:cover property itself.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Natesh bhat
  • 12,274
  • 10
  • 84
  • 125
1

Use this CSS:

background-size: 100% 100%

Shady Mohamed Sherif
  • 15,003
  • 4
  • 45
  • 54
0

Do you want to achieve this just using one image? Because you can actually make somewhat similar to a stretching background using two images. PNG images for instance.

I've done this before, and it's not that hard. Besides, I think stretching would just harm the quality of the background. And if you add a huge image it would slow down slow computers and browsers.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MarioRicalde
  • 9,131
  • 6
  • 40
  • 42
  • Good point. But i'm using jpg for the background image, shes is about 1500x1000 only takes little more than 100kb. But how did you do it? – Fábio Antunes Jul 19 '09 at 16:13
  • 1
    How about centering the image horizontally and soften the image edges with a solid color or a pattern? This would allow you to have a seamless adaptation if the user has more than the image resolution. – MarioRicalde Jul 19 '09 at 16:28
  • But i want that the image fills the background. The one your saying, thats what i usually do. – Fábio Antunes Jul 19 '09 at 19:05