What is the best way to center a fixed position background image within a container that is slightly shifted from the top of the viewport?

How can I center a background-image vertically, which has a fixed background-attachment and is positioned 100px from the top? The background-size property is set to cover for horizontal centering but the vertical alignment is off.

Below is the HTML code:

<div class="header">
  <h1>Header</h1>
</div>

<div class="container">
  <img src="http://i.imgur.com/LJubdtP.png">
</div>

<div class="crosshairs">
  <div class="xAxis"></div>
  <div class="yAxis"></div>
</div>

CSS code:

/* CSS styling reset */
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, /*sub, sup,*/ tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}

.header {
  width: 100%;
  height: 100px;
  background-color: tan;
  position: fixed;
  top: 0;
}

.container {
    width: 100%;
    margin-top: 100px;
    height: calc(100vh - 100px);
  background-image: url('http://i.imgur.com/EvdsgOV.png');
    background-position: center 100px;
    background-attachment: fixed;
    background-size: cover;
  text-align: center;
  position: relative;
  z-index: 50;
}

.container img {
  display: inline-block;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}

.crosshairs {
  width: 100%;
    margin-top: 100px;
    height: calc(100vh - 100px);
  position: absolute;
  top: 0;
}

.xAxis {
  width: 100%;
  height: 10px;
  background-color: red;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

.yAxis {
  width: 10px;
  height: 100%;
  background-color: red;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}

JavaScript code:

var backgroundImage = new Image();
backgroundImage.src = $('.container').css('background-image').replace(/"/g,"").replace(/url\(|\)$/ig, "");

backgroundImage.onload = function() {

  var object = $('.container');

  var bgImgWidth = this.width;
  var bgImgHeight = this.height;

  var imageRatio = bgImgWidth/bgImgHeight;
  var coverRatio = object.outerWidth()/object.outerHeight();

  if (imageRatio >= coverRatio) {
    /* The Height is our constant */
    var coverHeight = object.outerHeight();
    var scale = (coverHeight / bgImgHeight);
    var coverWidth = bgImgWidth * scale;
  } else {
    /* The Width is our constant */
    var coverWidth = object.outerWidth();
    var scale = (coverWidth / bgImgWidth);
    var coverHeight = bgImgHeight * scale;
  }
  var cover = coverWidth + 'px ' + coverHeight + 'px';

  var containerHeight = $('.container').height();
  var posFromTop = 100 + (containerHeight - coverHeight) * .5;
  console.log(coverHeight + ' coverHeight');
  console.log(containerHeight + ' containerHeight');
  console.log(posFromTop + ' posFromTop');
  $('.container').css('background-position', 'center ' + posFromTop + 'px');
};

The issue arises when viewport height exceeds 300px, causing incorrect calculation of coverHeight value. Here's the fiddle link for reference: https://jsfiddle.net/LxuxeL58/1/

Answer №1

Shifting it downward by just half the header's height should be effective even without using JavaScript.

Answer №2

It seems like the error in your code lies within the .outerWidth() and .outerHeight() functions.

Another potential source of the issue might be related to how you are using the "this" keyword, as it always references the caller of the function which could potentially be the window object in this scenario.

Based on my personal experience, I recommend using Element.getBoundingClientRect() for calculating width, height, and position - although this is just a suggestion and not necessarily the most optimal approach.

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

Incorporating an image into a list of checkboxes post-connection

Looking for a way to populate a checkbox list through datasource/databind and then integrate an image with each checkbox? I can do both separately but struggling to combine them successfully. My task is to create a checkbox list of students for teachers t ...

Transfer PDF file to user's web browser through XMLHttpRequest, utilizing up-to-date HTML5 techniques, all while maintaining the integrity of the document's encoding

I am trying to achieve a similar result as described in this StackOverflow post about handling file download from ajax post. However, I'm working with a dynamically-generated PDF file created using PHP v5.6.10 (with the PDFLib extension, v9.0.5). Unf ...

Trigger a function in jQuery when the DOM undergoes changes

Up until now, I have been utilizing livequery which has served its purpose. However, it tends to slow down the page browsing experience, so I am in search of an alternative solution. I have a function that performs ajax on elements with a specific class l ...

Encountering an Error with JsonRpcProvider while deploying a contract or attempting to run a node

An error has occurred: Error: ERROR processing skip func of /home/dylan/hh-fcc/hardhat-smartcontract-lottery-fcc/deploy/00-deploy-mocks.js: TypeError: Cannot read properties of undefined (reading 'JsonRpcProvider') While following the freecodeca ...

Creating a dynamic HTML table using Vue 3

My table is not showing the data I'm fetching from my API. Even though I can see the data in my console.log, it's not populating the table. Could there be an issue with how I'm calling the data to display in the table? <template> < ...

Having difficulty generating a footer for a page that includes a Material-UI Drawer component

Looking to create a standard full-width footer at the bottom of my page, I need help with the implementation. Utilizing the "Permanent drawer" from Material-UI Drawer for reference here. If you're interested in experimenting with it, CodeSandbox link ...

Positioning a button on the side of the screen while a hidden side panel is open

I am attempting to create an animation using a side panel that will slide into view when a button is clicked. Here is how it appears when the page loads: When the user clicks on one of the buttons, the notes panel will become visible like this: This is ...

Updating textbox values with ajax results in the page refreshing and the newly assigned values being lost

I'm currently working on updating a section of my webpage using AJAX instead of C#, as I don't want the page to refresh. All I need to do is execute a SELECT query to retrieve the current client from the SQL database and populate the correspondin ...

I need to use JavaScript to create HTML to PDF and then upload the PDF file to a SharePoint Document Library

Our current project requires us to convert HTML to PDF and save it in a SharePoint Document Library. While we have successfully converted the HTML to PDF using Kendo plugin, we are facing challenges with storing it in SharePoint. It's worth noting th ...

What is the best way to resize a Drawable to fit the width of a TextView?

When trying to render HTML with image tags within a TextView, I encountered issues with scaling the images using the getDrawable() code. Here is an example snippet of the code: myTextView.setText(Html.fromHtml(htmlSource, this, this)); @Override public Dr ...

Tips for transforming a Vue 2 website into a progressive web application (PWA) were requested

As I explored the PWA functionality in Vue 3, I noticed that it is not available in Vue 2. If anyone has any insights on how to successfully convert a Vue 2 project into a PWA, I would greatly appreciate your input. Thank you! ...

Difficulty with virtualization in the Kendo UI combo-box when dealing with limited local data sources

The issue I am facing is that the combo box is not loading items after filtering, specifically when dealing with a small set of data (around 10-60 items). To reproduce the problem, follow these steps: Filter an item (e.g. ZIORE) from the text box. Use t ...

Move the div by its handle without any nesting involved

When exploring the JQueryUI draggable demo, I noticed that you can attach a handle to a DIV. However, I found that if the handle is not nested within the parent DIV that is draggable, it doesn't work. For example: <script src="jquery-1.5.2.js"> ...

Searching text on an iPhone using regex patterns

Currently, I have been utilizing the following regular expression: <li class=\"b_algo\"><h2><a href=\"(.*?)\" In my search within NSString, I am interested in modifying this search to also include : <li class=\ ...

Tips for arranging divs in Bootstrap 5 to position one above the other

I have chosen to utilize Bootstrap 5 for my website project with the aim of enhancing its responsiveness on all devices. Specifically, I am seeking a way to ensure that when visitors access the site from a mobile device, the image-containing div appears a ...

What is the best way to send a request using an API key through a form submission method?

I encountered an issue while attempting to retrieve the json response through a form using the post method; I kept receiving a forbidden 403 error. window.onload = function() { document.getElementById("Save").onclick = function fun() { var x = docum ...

When utilizing a script to deliver a true or false response for jQuery's .load() function

Currently, I have found myself delving deep into jquery to manage the ajax requests in my web applications. Specifically, I am working on a bidding system in PHP that heavily relies on mod_rewrite. Using jQuery with a confirm dialog, I send an Ajax request ...

Trouble with Bootstrap Popover's visibility

My current setup involves a popover that is not initializing properly. The code I am using is shown below: HTML: <div data-toggle="popover" data-placement="bottom" data-content="xyz">...</div> JavaScript: $(function () { $('[data-t ...

Limiting multiple checkbox inputs in a React application can be easily achieved by utilizing React

Trying to create a form where the user can only check three boxes and uncheck them. The decrement on setCurrentData(currentData - 1) is not working as expected. Even after deselecting, the currentData remains at 3, preventing the user from checking any mo ...

Is there a way to swap out values in a JavaScript Object for new ones?

I need to update the initial values of myObject with new names: let myObject = [ { name: 'X0', values: 'FALSE,TRUE' } , { name: 'X1', values: 'NORMAL,LOW,HIGH' } , { name: 'X2', values: ' ...