Prevent CSS background resize caused by toggling the Chrome URL bar on Android devices

When browsing a website using Chrome for Android, the height of the view area changes when scrolling causes the URL bar to hide. This can lead to annoying resizing of a fixed background image, especially when scrolling down and back up again.

https://i.sstatic.net/42zKh.jpg

This issue has been previously discussed in the following threads:

  • Background image jumps when address bar hides iOS/Android/Mobile Chrome

A 'fix' was suggested, recommending the use of vh instead of % for defining the height of the image:

If a site includes a fixed background image:

<html>
  <head>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div id="content">
      <div style="padding-bottom:2000px; width:100%;">Test</div>
      <div>Test again</div>
    </div>
  </body>
</html>

using the following CSS:

html, body {
    margin: 0;
    padding: 0;
}

div {
    color:white;
    font-size: 30px;
}

#content {
    background: url(https://images.freeimages.com/images/large-previews/01a/technology-background-1632715.jpg) no-repeat right 15% center fixed;
    background-size: cover;
}

The background image will resize as described above on Google Chrome for Android. Here is a Fiddle.

The solutions proposed to address this issue involve using JavaScript to update the image height after window resizing occurs, but they do not fully prevent the background image from resizing without leaving gaps in the page.

To maintain the background image's position, two potential methods are suggested:

  • Preventing the URL bar from hiding
  • Rendering the image with an initial offset to compensate for the image shift

Preventing the URL Bar from Hiding

To keep the URL bar constantly visible, a fixed div containing a scrollable div container was created:

<div id="content">
  <div id="fixed">
    <div id="scroller">
      <div style="padding-bottom:2000px; width:100%;">Test</div>
      <div>Test again</div>
    </div>
  </div>
</div>

CSS:

#fixed {
    height:100vh;
    width:100vw;
    overflow:hidden;
}

#scroller {
    overflow-y: auto;
    height:100vh;
}

The concept involves preventing the user from scrolling the website body to avoid the URL bar disappearing. Although this method worked on an emulator, it did not function correctly on a real Galaxy S20 device, where users were still able to hide the URL bar by scrolling to the bottom of the page.

Rendering the Image with an Initial Offset for Compensation

Another approach was to initially draw the background image deeper:

background-size: auto calc(100vh + 100px);

If there is additional space at the top of the image, it could be possible to adjust the image position based on window height changes. However, this method may require adjusting both vertical and horizontal dimensions or rescaling the image. Attempting to determine the current image size using jQuery resulted in limited success as only the "auto" value was returned.

Most discussions on this topic date back over five years. Is there a modern solution to this challenge?

Update:

To prevent the background image from scaling, an approach involving calculating the image width relative to the scaled height and setting pixel-based background-size values was implemented:

var initHeight = '';
var initWidth = '';
var imageHeight = 982;
var imageWidth = 1500;
var cssHeight;
var cssWidth;

$(window).on('resize', function () {
  if (initHeight == 0) {
    initHeight = $(window).height();
    initWidth = $(window).width();
    cssHeight = parseInt($('#content').css('background-size').split(" ")[1].slice(0,-2));
    cssWidth = cssHeight / imageHeight * imageWidth;
    $('#background').css('background-size', cssWidth + "px " + cssHeight + "px");
}

Now, the background image remains static without scaling but adjusts vertically when toggling the URL bar.

To eliminate this movement, the alternative method of rendering the image with an initial offset was employed:

background: url(../images/bg.jpg) no-repeat right 15% top -100px;
background-size: auto calc(100vh + 200px);

Upon detecting a resize event, the background image position is updated accordingly:

let newHeight = $(window).height();
let newWidth = $(window).width();
let diff = newHeight - initHeight;
$('#background').css('background-position', "85% " + (startHeightOffset + diff) + "px")

This solution appears effective on an emulator, maintaining the image's position. However, testing across devices revealed issues with devices featuring toolbars at the bottom. Implementing adjustments specific to the top URL bar height only proved challenging.

In order to address this challenge, one must focus on:

  • Reliably preventing URL bar collapse
  • Determining the height of the bottom toolbar

Update 2:

A workaround to prevent URL bar hiding was achieved through styling adjustments:

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    overflow: scroll;
}
body {
    -webkit-overflow-scrolling:touch;
}

#content {
    width: 100%;
    height: 100%;
    background: url(https://images.freeimages.com/images/large-previews/01a/technology-background-1632715.jpg) no-repeat right 15% center fixed;
    background-size: cover;
}

#fixed {
    height:100%;
    width:100vw;
    overflow:hidden;
}

#scroller {
    overflow-y: auto;
    height:100vh;
}

While this method maintains the background image's position by preventing URL bar collapse, it is not considered an ideal solution. Finding a way to achieve this without relying on blocking URL bar collapse would be preferable.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Managing output buffers, styling with CSS, and sending emails with PHP

I am currently using a script to send emails that result in a couple of HTML tables: $from = "example.com <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="82efebe7ef83898ce0ede1e9e3e6d2edeee8">[email protected]</a ...

What is the process for obscuring items using the depth buffer in three.js?

In my current project using three.js, I am working on a 2D game where I need to render background scenery followed by a transparent quad that still writes values to the depth buffer even though it has an opacity of zero. The challenge arises when trying to ...

Challenges with XML parsing in Ajax and jQuery

Encountering an Issue: Add "undefined" for each element. I've spent hours researching solutions to this problem, but have not been able to find a resolution. Apologies if this question has been asked numerous times before. I am attempting to retriev ...

CoffeeScript's alert feature appears to be malfunctioning

After stumbling upon CoffeeScript in a blog post, I was excited to try it out. My first attempt at using it involved this code snippet: alert "Hello CoffeeScript!" Unfortunately, it didn't work as expected and produced the following error message: ...

How to retrieve the image source from a block using jQuery

Currently, I am working on developing a slider for my webpage using jquery's "Cycle" plugin. However, I have encountered an issue with accessing the image sources used in the slider. To provide more context, here is a snippet of code from the 'he ...

Unusual CSS media queries behavior

During my project work, I faced a puzzling issue which can be illustrated with the following example: Here is the sample CSS code: *, *::after, *::before { box-sizing: border-box; margin: 0; border: 0; } @media only screen and (max-width ...

Submitting the form does not result in the textbox being cleared

I have been attempting to clear the txtSubTotal text box upon clicking the PROCEED button, but it seems that my efforts have been in vain despite trying various code examples, including those from SO. btnProceed/HTML <input type="submit" name="btnProc ...

Troubles with Geocoding functionality on Google Maps integration within Wordpress

I have a challenge where I want to utilize the title of a Wordpress post (a specific location) as a visible marker on a Google map. The code provided by Google successfully displays the map without any markers: <script>function initialize() { va ...

Is it possible to utilize CSS rules for a non-existent div within CSS?

Can this be achieved using CSS? If .div1 is not present, enforce the following rule: .div2{ property: value; } For example, <div class="div1"> ... </div> <div class="div2"> <!-- it exists, so no action needed --> </div& ...

Unique element is bound with jQuery's ajaxStart function

Below is the JS code I am working with: <script type="text/javascript"> $(document).ready(function () { $("#innerDiv1").ajaxStart(function () { alert($(this).attr("id") + " ajaxStart"); }); $("#innerDiv2").aj ...

Can a .p12 or .pfx file be imported into Selenium Webdriver using only code?

Hey there everyone! I ran into an issue while trying to write one of my end-to-end tests. I want to log in to my application using a certificate, but I'm not sure if it's possible to do this purely through code. I've spent several days sea ...

problem with increasing/decreasing buttons in a react application

My goal is to display a list of Names in a specific order, but I'm encountering an issue when using the increment and decrement buttons. When I click the increment button, the order increases by 1 as expected. However, when I click the decrement butto ...

Using Selenium Webdriver to target and trigger an onclick event through a CSS selector on a flight booking

I've been running an automation test on the website . When searching for a flight, I encountered an issue where I was unable to click on a particular flight. I initially tried using Xpath but it wasn't able to locate the element when it was at th ...

Javascript's simplistic addition function is not functioning properly

Learning JavaScript has been a bit challenging for me, especially when it comes to simple concepts. I'm trying to write code that sums two numbers together, but for some reason, it's not working. function sum() { var number1 = documen ...

Javascript: A Fun Game of Questions and Answers

When using JavaScript exclusively, I have an array consisting of four questions, four correct answers, and four incorrect answers. The use of arrays is essential to maintain order in the data. As each question is displayed, a random number is generated by ...

Retrieve the URL and store it | Browser Add-on

I'm looking to create a feature where, upon clicking an icon on my window, it will open and display the URL of the current tab. Next to the URL, I want a "Save" button that will store the link in localStorage and show it below in the saved links area. ...

Is there a way to convert a URL into a clickable link and retrieve the YouTube code embedded within

I have retrieved a string from the database using PHP and I want to echo it. Within this string, there is a YouTube link that I would like to make clickable, as well as extract the YouTube code at the end of the link. How can I achieve this? For example: ...

What is the best way to incorporate modules into the client side of TypeScript projects?

I'm currently developing a TypeScript project for client-side JavaScript code. Prior to using TypeScript, I used to import a module in vanilla ES6 JavaScript like this: import * as THREE from 'https://threejs.org/build/three.module.js'; H ...

Position the text on the left side while also centering it within my div

I am attempting to center align some links within my div, while also ensuring that the text of the links is aligned to the left. However, I have been unsuccessful in achieving this. I can either align them to the left or center, but not both simultaneousl ...

Unable to figure out why information is not being transferred to an array through Mongoose

Seeking assistance as I am unable to figure out how to place a set of information into an array named "teamDetails". Here is the relevant /post item from server.js: app.post('/create', (req, res) => { console.log('Post command receiv ...