CSS fullscreen background shows whitebar at bottom when scrolling on mobile

Viewed 2131

I have a website with a fullscreen background image.

html, body {
  height: 100vh;
}

html {
  background: url('/img/background.jpg') no-repeat center center fixed;
  background-size: cover;
}

This code works fine on most devices, but on some old Android devices, this causes a problem when scrolling down. Partially scrolling down, but not releasing your finger shows a white bar equal in size to the URL bar that is disappearing at the same time. Once you release your finger the background fixes itself.

This is what the image looks like mid-scroll.

screenshot of website

Is there a way to make sure the background is always filling the page?


Edit: I have also tried adding a div with these properties:

#background {
  background: url('/img/background.jpg') no-repeat center center fixed;
  background-size: cover;
  z-index: -100;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 200vh;
}

This shows the background but the same problem occurs.

10 Answers

On IOS and newer Android devices, vh has been fixed so that 100vh is always the height between the bottom of the minimal top bar and the bottom of the screen.

In older devices this was not so, so vh changes when the user gets rid of some of the browsers top bars by scrolling.

This fixing was introduced to stop the phenomenon you are seeing, and potential ‘jumping’ in size of elements when scrolling. It has introduced another problem which is that not all your background will show when the user first enters the page.

In your case this isn’t noticeable because of the solid color for some distance at the bottom of your image. It would matter if there was text near the bottom.

You could perhaps get round your problem by having an absolutely placed element, or a pseudo element, which had the same background but at 100vh plus a bit. This might work, ie. it give a visible join, given the nature of your image.

Not a general solution though, I realise.

You could try using a pseudo element, it might be a bit work do to, but it could potentially fix the issue, like so

html, body {
height: 100vh;
width: 100vw;
position: relative;
z-index: 2;
}

body::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 100%;
background: url('/img/background.jpg');
background-repeat: no-repeat;
background-position: center;
background-size: cover;
z-index: 1;
}

I didn't know how to do this, so I looked it up. Safari has the tendency to do this on all websites, but you may be able to fix it for your case. I have found a few similar questions on Stack Overflow on how to fix it. I will present some of the solutions below:

Add a scroll class to your background

html,
body {
 height: 100%;
 margin: 0;
 overflow: hidden;
}
.scroll {
 overflow: auto;
 height: 100%;
}

Prevent overflow scrolling

html,
body {
 -webkit-overflow-scrolling: auto;
}

Using the iNoBounce Library

This library can be found here. This should be your last resort in the case that the other methods don't work. The owners have not released a new update since 2018, but for now it has worked through my tests. Happy Coding :)

Try this. It will make your background always filling the page

html, body {
  height: 100vh;
}

html {
  background: url('/img/background.jpg') no-repeat center center fixed;
  background-size: cover;

  position: absolute;
}

try this : 420 is a common mobile screen size. ??? is based on your elements height

@media screen and (max-width: 420px) {
  .sampleCSSclass {
    height: calc(100vh - ????px);
  }
}

If the scrollbar is totaly not used you can add oveflow hidden to body and no overflow will be vissible. Try to set margin and padding to 0

That's because of height: 100vh; You need to increase height. Maybe you should try height:100% or try min-height: 100vh;

  1. Use -webkit-fill-available

    https://css-tricks.com/css-fix-for-100vh-in-mobile-webkit/

  2. I had a similar problem that I had to calculate the height of a body without safari toolbar. came up with this solution. Don't Know if its working for you too or not:

    body { height: 100vh; height: calc(var(--vh, 1vh) * 100); }

The issue is background-attachment: fixed; Things work fine if the image scrolls with the div it belongs to, but as soon as its fixed it takes up 100vh.

Ive been at this for longer then i'd like to admit and havent found a solution yet.

It seemingly just doesnt not want to listen to the actual div height; In my case, (using background-size: cover;) the innerHeight (100vh) reads 653px when the toolbar is active, and 709px when the toolbar disappears.

While typing this i did a simple test (on Firefox mobile:

So i used fixed height and auto width on the background image, using an image that has a simple red line at the bottom:

  1. Using height: 653 - the red line in the image shows (obviously)
  2. Using height 709 - the red line does not show when the toolbar disappears!

Which means that the pixels obstructed by the toolbar are just simply not being rendered when the toolbar disappears. Event though they should in my logic..

EDIT: I thought i had a solution: place a div behind the rest of the site that holds (and stacks if you have a background per section like i do) in a wrapper. Set this to absolute and use javascript to get the element's offset top (of which the background is supposed to belong to) and offset the background's "top" property to be equal the the div it belongs to. I tried using the offsetTop property to match the offsets, but havent made it work yet.

But theoretical, one could then use position sticky on the background images to mimic the position fixed effect without content jumps or the annoying (seeming) bug.

Related