57

Hi I have several divs on my page which have background images that I want to expand to cover the entire div which in turn can expand to fill the width of the viewport.

Obviously background-size: cover behaves unexpectedly on iOS devices. I've seen some examples of how to fix it, but I can't make them work in my situation. Ideally I'd prefer not to add extra <img> tags to the HTML but if it's the only way then I will.

Here is my code:

.section {
  margin: 0 auto;
  position: relative;
  padding: 0 0 320px 0;
  width: 100%;
}

#section1 {
  background: url(...) 50% 0 no-repeat fixed;
  background-size: cover;
}

#section2 {
  background: url(...) 50% 0 no-repeat fixed;
  background-size: cover;
}

#section3 {
  background: url(...) 50% 0 no-repeat fixed;
  background-size: cover;
}
<body>
  <div id="section1" class="section">
    ...
  </div>
  <div id="section2" class="section">
    ...
  </div>
  <div id="section3" class="section">
    ...
  </div>
</body>

The question is, how can I get the background image to completely cover the section div, taking into account the variable width of the browser and the variable height of the content in the div?

kizoso
  • 1,216
  • 2
  • 15
  • 30
Josh
  • 3,445
  • 5
  • 37
  • 55

10 Answers10

146

I have had a similar issue recently and realised that it's not due to background-size:cover but background-attachment:fixed.

I solved the issue by using a media query for iPhone and setting background-attachment property to scroll.

For my case:

.cover {
    background-size: cover;
    background-attachment: fixed;
    background-position: center center;

    @media (max-width: @iphone-screen) {
        background-attachment: scroll;
    }
}

Edit: The code block is in LESS and assumes a pre-defined variable for @iphone-screen. Thanks for the notice @stephband.

Community
  • 1
  • 1
mkubilayk
  • 2,477
  • 3
  • 20
  • 27
  • This worked well for me. The selected correct answer worked well for the background image but messed up some other elements on my page. – dshap Jun 13 '14 at 16:25
  • Actually, maybe not. It seems now the page can be scrolled away horizontally :( I guess that makes sense given the property being set – dshap Jun 13 '14 at 16:36
  • Yes, this will not provide the same scrolling experience. However it might be a small fix in order not to re-design interfaces from scratch for mobile devices. – mkubilayk Jun 16 '14 at 07:51
  • 32
    You should make it clear you're using SASS or something here. A novice may wonder why that code does not work in their CSS. – stephband Jun 29 '15 at 20:13
  • @stephband just included a note in the original post, thanks! – mkubilayk Aug 24 '15 at 08:16
  • 4
    chalk this under "answers I desperately needed that I almost missed because the chosen answer wasnt what I needed". – Daniel Gomez Aug 30 '16 at 02:28
  • This solution creates a whitespace at the bottom of the element. The background doesn't cover the whole element, so for me it's not the solution. Still searching for one. – Ionut Necula Nov 19 '16 at 15:53
  • 1
    When setting the max-width don't forget to account for the mobile device being in landscape orientation, otherwise the media query won't trigger when in landscape and you'll have the same problem. – andydavies Mar 04 '17 at 10:46
  • This is a great solution. After a few hours of trying some others- this is correct. Thanks! – only_one Sep 16 '20 at 18:53
16

I've had this issue on a lot of mobile views I've recently built.

My solution is still a pure CSS Fallback

http://css-tricks.com/perfect-full-page-background-image/ as three great methods, the latter two are fall backs for when CSS3's cover doesn't work.

HTML

<img src="images/bg.jpg" id="bg" alt="">

CSS

#bg {
  position: fixed; 
  top: 0; 
  left: 0; 

  /* Preserve aspect ratio */
  min-width: 100%;
  min-height: 100%;
}
ckuijjer
  • 13,293
  • 3
  • 40
  • 45
Zone6
  • 314
  • 2
  • 4
  • Thanks. I think I'm going to need to use the javascript solution in the link provided as I want to use the largest possible image, and this solution only scales the images down. – Josh Aug 25 '13 at 22:59
  • 6
    The problem with this solution is it only works for a single image. The question owner situation are having different sections, so the section need to be scrollable. – Jimmy Chu Apr 23 '14 at 10:38
  • In case you want to center the image, just add `right:0;bottom:0;margin:auto;` – yckart Aug 13 '15 at 10:39
  • When I use this, it causes the image to "stretch to fit", which is undesired. – Choylton B. Higginbottom Nov 13 '16 at 02:22
6

Also posted here: "background-size: cover" does not cover mobile screen

This works on Android 4.1.2 and iOS 6.1.3 (iPhone 4) and switches for desktop. Written for responsive sites.

Just in case, in your HTML head, something like this:

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>

HTML:

<div class="html-mobile-background"></div>

CSS:

html {
    /* Whatever you want */
}
.html-mobile-background {
    position: fixed;
    z-index: -1;
    top: 0;
    left: 0;
    width: 100%;
    height: 125%; /* To compensate for mobile browser address bar space */
    background: url(/images/bg.jpg) no-repeat; 
    background-size: 100% 100%;
}

@media (min-width: 600px) {
    html {
        background: url(/images/bg.jpg) no-repeat center center fixed; 
        background-size: cover;
    }
    .html-mobile-background {
        display: none;
    }
}
Community
  • 1
  • 1
Modular
  • 6,440
  • 2
  • 35
  • 38
5

There are answers over the net that try to solve this, however none of them functioned correctly for me. Goal: put a background image on the body and have background-size: cover; work mobile, without media queries, overflows, or hacky z-index: -1; position: absolute; overlays.

Here is what I did to solve this. It works on Chrome on Android even when keyboard drawer is active. If someone wants to test iPhone that would be cool:

body {
    background: #FFFFFF url('../image/something.jpg') no-repeat fixed top center;
    background-size: cover;
    -webkit-background-size: cover; /* safari may need this */
}

Here is the magic. Treat html like a wrapper with a ratio enforced height relative to the actual viewport. You know the classic responsive tag <meta name="viewport" content="width=device-width, initial-scale=1">? This is why the vh is used. Also, on the surface it would seem like body should get these rules, and it may look ok...until a change of height like when the keyboard opens up.

html {
    height: 100vh; /* set viewport constraint */
    min-height: 100%; /* enforce height */
}
dhaupin
  • 1,613
  • 2
  • 21
  • 24
  • This worked for me once I removed the ```background-attachment: fixed;```, which appears to be the root cause of the background issue on iOS – gazzwi86 Oct 08 '16 at 01:21
1

That its the correct code of background size :

<div class="html-mobile-background">
</div>
<style type="text/css">
html {
    /* Whatever you want */
}
.html-mobile-background {
    position: fixed;
    z-index: -1;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%; /* To compensate for mobile browser address bar space */
    background: url(YOUR BACKGROUND URL HERE) no-repeat; 
 center center fixed; 
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
 background-size: 100% 100%
}
</style>
supetcriss
  • 11
  • 1
0

For Safari versions <5.1 the css3 property background-size doesn't work. In such cases you need webkit.

So you need to use -webkit-background-size attribute to specify the background-size.

Hence use -webkit-background-size:cover.

Reference-Safari versions using webkit

Rajesh Paul
  • 6,793
  • 6
  • 40
  • 57
0

I found the following on Stephen Gilbert's website - http://stephen.io/mediaqueries/. It includes additional devices and their orientations. Works for me!

Note: If you copy the code from his site, you'll want to edit it for extra spaces, depending on the editor you're using.

/*iPad in portrait & landscape*/
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) { /* STYLES GO HERE */}

/*iPad in landscape*/
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) { /* STYLES GO HERE */}

/*iPad in portrait*/
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) { /* STYLES GO HERE */ }
Mason
  • 19
  • 2
0
@media (max-width: @iphone-screen) {
  background-attachment:inherit;    
  background-size:cover;
  -webkit-background-size:cover;
}
  • Can you explain a bit more? – Dieter Meemken May 12 '16 at 08:01
  • -webkit-background-size:cover; is not working fine with css property background-attachment:fixed; so we can use like this @media (max-width: @iphone-screen) { background-attachment:inherit; background-size:cover; -webkit-background-size:cover; } – Amit Nanda May 14 '16 at 05:25
-1

I found a working solution, the following CSS code example is targeting the iPad:

@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) {

    html {  
        height: 100%;
        overflow: hidden;
        background: url('http://url.com/image.jpg') no-repeat top center fixed;
        background-size: cover; 
    }

    body {  
        height:100%;
        overflow: scroll;
        -webkit-overflow-scrolling: touch;
    }

}

Reference link: https://www.jotform.com/answers/565598-Page-background-image-scales-massively-when-form-viewed-on-iPad

Paul Vincent Beigang
  • 2,972
  • 2
  • 16
  • 31
-2
html body {
  background: url(/assets/images/header-bg.jpg) no-repeat top center fixed;
  width: 100%;
  height: 100%;
  min-width: 100%;
  min-height: 100%;

  -webkit-background-size: auto auto;
  -moz-background-size: auto auto;
  -o-background-size: auto auto;
  background-size: auto auto;
}
Pascal
  • 1