Tackling the sticky header problem with in-browser anchoring and CSS dynamic height restrictions

I am experimenting with a unique combination of a Pure CSS in-page anchoring solution using scroll-behavior: smooth and scroll-margin-top settings, along with a sticky header for in-page navigation.

By utilizing IntersectionObserver, I can identify when the sticky element reaches the top of the page and dynamically apply specific styles to create a sticky header effect, which may change the header's height.

When the header is in its sticky position, users can smoothly scroll to different sections by clicking on links in the in-page sticky navigation, with proper offset adjustment.

The challenge lies in the initial state of the page load and clicking an anchor. If you click on an anchor while the header is not yet sticky, you will scroll to the correct section but with an incorrect offset position. Is there a way to resolve this issue without resorting to a JavaScript solution?

To illustrate these issues, I have created a basic Codepen. For instance, if you click on "Section C" upon page load, it will take you to the wrong offset. However, clicking on "Section C" again after that should lead you to the correct position, as well as other sections. When you initially click on an anchor while the header is not sticky, it will likely take you to the wrong section offset.

Answer №1

The isSticky class is being applied too early. To address this issue, a simple solution is to introduce a 500ms delay using the setTimeout function.
Although there is still a slight visibility of the effect, the final positioning is now accurate.

const watchHeader = () => {
  console.log(this);
  const header = document.querySelector(".test");
  console.log(header);
  const ioOptions = {
    root: document,
    rootMargin: "0px 0px -100% 0px",
    threshold: 0
  };
  const ioCallback = ([e]) => {
    console.log(e);
    setTimeout( () => e.target.classList.toggle("isSticky", e.isIntersecting), 500 );  // Addition made here
  };
  const observer = new IntersectionObserver(ioCallback, ioOptions);
  observer.observe(header);
};

watchHeader();

Link to Updated CodePen

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

Update the styling for the second list item within a specified unordered list class instantaneously

Looking to emphasize the second list item (li) within a selected dropdown list with a designated unordered list class of "chosen-results". <div class="chosen-container chosen-container-single select-or-other-select form-select required chosen-proc ...

Whenever I attempt to include state in a React class that is declared as a constant, I consistently encounter the error message: "TypeError:

Apologies for the redundancy, but as a newcomer to React, I previously inquired about a similar issue and have since modified my code. My current challenge involves trying to access a state value within a const React class. Below is the excerpt from my Ar ...

Tips for effectively showcasing JSON in an Angular directive

I am facing an issue with my Angular app that utilizes ui-router. I have set up a service and directive, but I am unable to display JSON data. Surprisingly, it works perfectly fine without the directive when I directly display it in the main template (home ...

Assistance with Collision Detection in HTML5 Canvas using JavaScript

Attempting to create a platformer game using HTML5 and the canvas feature. I managed to implement collision detection with rectangles, but encountered issues when adding multiple rectangles. I have a function that adds new objects to an array with attribut ...

Looking to identify the type of a adorned class in Typescript?

Consider the following scenario: return function IsDefined(object: any, propertyName: string) { .... ] We then go ahead and decorate a property like this: class Test { @IsDefined() p1: String = ""; } Now, when we execute a test inside the ...

Having an issue with Jquery selector where the text does not match

HTML Code <select id="myDropdown"> <option selected="selected" value="0">default</option> <option value="1">bananas</option> <option value="2">pears</option> </select> Javascript Function setDr ...

The issue causing "ReferenceError: fetch is not defined" is causing the test to fail

There seems to be an issue with my project where 'node-fetch' is installed, but the rest of the files are not importing it and the tests are not failing import { IQuery } from 'models/IQuery.interface'; import { NextApiRequest, NextApiR ...

Xpath merging HTML elements or nodes

<tr id="computer-report-tbl-row-0" ng-repeat="item in table.data.items" class="ng-scope" style=""> <td id="column-name-0" class="table-cell-md" sc-ellipsis-title="" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"> ...

JavaScript: Append an ellipsis to strings longer than 50 characters

Can the ternary operator be utilized to append '...' if a string surpasses 50 characters? I attempted this approach, however it did not work as expected. {post.title.substring(0, 50) + post.title.length > 50 ? '...&ap ...

Exploring AngularJS tab navigation and injecting modules into the system

Two separate modules are defined in first.js and second.js respectively: first.js var app = angular.module('first',['ngGrid']); app.controller('firstTest',function($scope)) { ... }); second.js var app = angular.mo ...

Angular framework does not trigger the button click event

Currently, I am in the process of creating a web app and working on designing the register page. My experience with Angular is still at a beginner level. The following code snippet is from the resiger.component.ts file: /** * To create a new User ...

Troubleshooting the Problem of Uneven Heights in Bootstrap Columns

I am facing an issue with a dropdown inside a Bootstrap grid. When I click on the dropdown, the height of the row is not increasing as expected. Can anyone guide me on how to achieve this? HTML: <div class="container"> <div class=& ...

Searching through multiple columns in datatables

I encountered an issue with searching multiple columns in my serverside datatables. Individual column searches work fine, but when trying to search on more than one column simultaneously, the filter does not function as expected. For example, searching by ...

What could be the reason for my form submission redirecting to the PHP page?

(I recently discovered that I could edit and reopen the post I had previously made. Feeling a bit confused about the process...) After submitting the form, the email is sent successfully, but then I am redirected to my php page displaying the number 0. Th ...

AngularJS: Issue with inputMask functionality within an angularJS table

Within my ng-repeat table, I have two date fields. Here is the code snippet: <tr ng-repeat="ol in orderLines"> <td> <input class="audioStartTime" type="text" ng-model="ol.AudioStartTime"/> </td> <td> ...

Is it possible to reload the webpage just one time after the form is submitted?

Can anyone suggest how I can refresh the webpage using PHP after submitting a form? I've been searching for a solution but haven't found one yet. Your assistance would be greatly appreciated. ...

I am experiencing difficulties with the PHP login form on MAMP as it is not loading properly, displaying only a

Having trouble with php not loading when I open my browser. Here is my database info: MySQL To manage the MySQL Database, you can use phpMyAdmin. If you need to connect to the MySQL Server from your own scripts, use these connection parameters: Host ...

Seeking assistance with creating an iPad application utilizing JQtouch - any t

I am attempting to create an iPad app using jQuery and jQTouch for the second time. I want to split the existing jQTouch theme designed for iPhone, which uses one window, into two separate windows optimized for the iPad. My goal is to have navigation on t ...

Storing customer information securely on the server with the help of Node.js

After spending some time experimenting with Node.js on my local machine, I've realized that my understanding of HTTP requests and XHR objects is quite limited. One particular challenge I've encountered while using Node is figuring out how to effe ...

"The Ajax function for replacing a div upon change event is not functioning properly

I am having an issue with my select box using the onchange event, <select class="form-control" onchange="getval(this.value,'<?php echo $prd->pr_id;?>','ajax<?php echo $key?>','<?php echo $key ?>')"&g ...