When CSS is modified by inserting an extra div, it causes the positioning of other elements to shift towards

I'm currently working on adapting a method to make elements "sticky" for older browsers as discussed in this particular article.

The basic idea involves implementing some JavaScript code that listens for scroll events. Upon detection of such an event, it applies the style rule position: fixed to the specified element to keep it in place while the user scrolls. To prevent any disruption in the page layout when the element becomes fixed, an identically sized div is inserted before the fixed element.

While this approach works well in general, I've encountered difficulties getting it to function properly on my web page due to my attempt to fix a right-hand div within a two-column layout. Despite setting the width of the element to match the sticky element, the menu shifts to the left once it becomes "stuck".

The CSS classes used for positioning the right-hand column are as follows:

.objects {
    margin: 10px 30px;
    float: right;
    display: inline-block;
    text-align: center;
    top: 30px;
    width: 40%;
}

.objects .content-block {
  margin: 0px;
  width: 100%;
}

<div class="objects" id="sticky">
    <div class="content-block">
    </div>
</div>

Here is the JavaScript code being employed:

var menu = document.querySelector('#sticky');
var menuPosition = menu.getBoundingClientRect();
var placeholder = document.createElement('div');
placeholder.style.width = menuPosition.width + 'px';
var isAdded = false;

document.getElementById("content").addEventListener('scroll', function() {
  if (document.getElementById("content").scrollTop >= menuPosition.top && !isAdded) {

    menu.classList.add('sticky');
    menu.parentNode.insertBefore(placeholder, menu);

    isAdded = true;
  } else if (document.getElementById("content").scrollTop < menuPosition.top && isAdded) {

    menu.classList.remove('sticky');
    menu.parentNode.removeChild(placeholder);

    isAdded = false;
  }
});

Interestingly, adjusting the width of the "placeholder" element doesn't seem to have any effect.

A detailed description of the issue can be found in this provided fiddle.

I'm seeking guidance on what changes need to be made in the CSS to ensure that the element stays in its original position within the right-hand column.

Answer №1

My suggestion is to make adjustments to the width in order for it to work smoothly with both static and fixed positions (using the vw unit). A 40% width may not behave consistently when the element's container does not have a width of 100%.

You should also include right:17px (which corresponds to the scroll bar width). When combined with position:fixed, right:17px will mimic the behavior of float:right in this specific scenario.

let menu = document.querySelector('#sticky');
let menuPosition = menu.getBoundingClientRect();
let placeholder = document.createElement('div');
let isAdded = false;

document.getElementById("content").addEventListener('scroll', function() {
if (document.getElementById("content").scrollTop >= menuPosition.top &&!isAdded) {

menu.classList.add('sticky');
menu.parentNode.insertBefore(placeholder, menu);

isAdded = true;
} else if (document.getElementById("content").scrollTop < menuPosition.top &&isAdded) {

menu.classList.remove('sticky');
menu.parentNode.removeChild(placeholder);

isAdded = false;
}
});
.drop-table {
display: inline-block;
width: 45%;
}

.objects {
margin: 10px 30px;
float: right;
display: inline-block;
text-align: center;
top: 30px;
width: 40vw;
right:17px;
}

.objects .content-block {
margin: 0px;
width: 100%;
}

#content {
position: fixed;
top: 40px;
bottom: 80px;
left: 0;
right: 0;
background-color: white;
overflow: auto;
z-index: 4;
}

.sticky {
top: 40px;
position: fixed;
}
<div id="content">
<div>

    <div class="content-block drop-table">
      <ul>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
        <li>AAA</li>
      </ul>
    </div>
    <div class="objects" id="sticky">
        <div class="content-block">
          <div>
            Assign
          </div>
        </div>
    </div>
    </div></div>

Answer №2

Utilize getComputedStyle(menu).width
and getComputedStyle(menu).height to accurately determine the size of your fixed element. It's important to also include the objects class on your placeholder to ensure it is positioned correctly in relation to the original object.

Answer №3

In order to utilize the position: fixed attribute effectively, it is crucial to define the element's positioning within the container block using attributes like top and right. Combining a "right" value (e.g. right: 0) with "top" for the .fixed class should produce the desired outcome.

Visit this link for more information on CSS position property

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

Display or conceal nested divs within ng-repeat loop

I set up a div with sub divs to establish a nested grid system. There are three levels altogether: MainDiv - Always Visible SecondDiv - Display or conceal when MainDiv is clicked on ThirdDiv - Display or conceal when SecondDiv is clicked on <div c ...

What is the most effective method for incorporating multi-line breadcrumb links in a React application?

I am currently working on implementing a multiline breadcrumb link feature for mobile and tablet devices. As users navigate through multiple folders, I need to handle scenarios where the number of links exceeds the maximum allowed in the breadcrumb contain ...

PHP - Implementing a Submit Button and Modal Pop-up AJAX across multiple browsers in PHP

As a newbie in PHP AJAX coding, I'm facing a challenge with having two browsers. My goal is to click the submit button on one browser and have a modal popup on the other browser simultaneously. Essentially creating a chat system where only a button an ...

Assign separate classes to even and odd div elements

My PHP code block has this structure: $flag = false; if (empty($links)) { echo '<h1>You have no uploaded images</h1><br />'; } foreach ($links as $link) { $extension = substr($link, -3); $image_name = ($extensi ...

Guide to implementing a universal animated background with Angular components

I'm having trouble figuring out why, but every time I attempt to use a specific code (for example: https://codepen.io/plavookac/pen/QMwObb), when applying it to my index.html file (the main one), it ends up displaying on top of my content and makes ev ...

I have been dynamically inserting div elements into the DOM using JavaScript, using the appendChild method to add them and later removing them with removeChild. Strangely, when trying to append a div

There seems to be an issue in the code snippet below. The function create() works fine the first time, but encounters a problem on the second run at the line boxWrapper.appendChild(box);. It appears that the removeChild method is causing some disruption in ...

Tips for executing parallax designs, similar to the techniques used on the

Currently, I am in the process of creating a website that utilizes parallax scrolling. Here is a brief overview of what I have accomplished thus far. I decided to use the skrollr plugin to achieve the desired parallax effect. Through this plugin, I was abl ...

What is the best way to update image CSS following a rotation using JavaScript?

Discover a neat CSS trick for always centering an image in a div, regardless of its size or aspect ratio. <style> .img_wrap { padding-bottom: 56.25%; width: 100%; position: relative; overflow: hidden; } #imgpreview { display: bl ...

Using an if statement to run a script in Npm

Is there a way to configure an npm run script to use different AWS accounts based on the environment? { "config": { "acc": if ({npm_config_env} == "dev") "account1" else "account_2" }, "scr ...

The printer is malfunctioning

My webpage has a div that includes various input fields with values assigned using jQuery. I wanted to print the contents of this div, so I found some code online to help me achieve this. However, when I try to print, the values in the input fields end up ...

Is it possible to include line breaks within a CSS value?

(I am posting this here because I couldn't find a solution and eventually figured it out through trial and error. Hopefully, this information can help others with the same question.) Note: This is not the same as the discussion on Single-line vs mult ...

What steps should be taken to enable the "You and moderator can reply" feature in a bot when sending proactive messages to channels?

A project I am currently working on involves creating a bot that sends proactive messages to channels. The client has requested that I include options like No reply or You and moderator can reply with the messages posted by the bot proactively. Here is wh ...

Tips for retrieving specific information from Wikipedia using AJAX

Is there a way to retrieve the information consistently displayed in the right box during searches using AJAX? I've tried using the Wikipedia API, but haven't been able to find the specific information I need. https://i.sstatic.net/wqJEc.png ...

Issue encountered when attempting to invoke a service from an Angular component within an office.js dialog

Our application utilizes Angular 5 and integrates Office.js to interact with Microsoft Office Word documents. Step 1: We use office displayDialogAsync to load the component. https://i.sstatic.net/uhT66.png Step 2: Inside the attribute-users component, an ...

Transforming jquery code into angularjsAre you looking to migrate your

I am currently struggling with converting a jQuery function into an AngularJS function. Here is the specific code snippet: $('p').each(function() { $(this).html($(this).text().split(/([\.\?!])(?= )/).map( function(v){return '< ...

Modify the text of a button when hovered over (JavaFX)

Can anyone help me figure out how to change the text of a button when it is hovered over? Approach: if (button.isHover()){ button.setText("new message"); } I'm open to either a css fix or a code solution! ...

Need help with JQuery mouseOver fading in twice when you only want it to fade in

The version can be displayed here. I'm looking to have the current text fade away and the new text fade in. Strangely, it seems to fade in twice for some reason. $(window).load(function(){ var originalTitle = $('.Pinctitle').text(); $(&apo ...

Achieving the retrieval of all data can be done simply by utilizing the `echo json_encode($data);

I am trying to automatically update the user wall with new data from the database using a script that checks for updates every 15 seconds. Everything works fine when I only use one piece of data like $data = $row['description']; in the server.ph ...

JavaScript - Attempting to insert a value into a text field by clicking a button

I am struggling to get my function to properly add the value of the button to the text field when clicked by the user. HTML <form name="testing" action="test.php" method="get">Chords: <textarea name="field"& ...

Vue.js does not support sorting columns

In this specific codepen example, I have created a Vue table that allows for sorting by clicking on the column name. Although I can successfully retrieve the column name in the function and log it to the console, the columns are not sorting as expected. Wh ...