Verify if the DIV element has a sticky positioning property

I'm utilizing the Bootstrap 4 "sticky-top" class (for position: sticky) to affix elements to the top.

Is there a method to include an additional class like "is-sticky-top" to the DIV when it becomes "stuck"?

Although I came across some resources, such as this one, I struggled to adapt it to suit my requirements: https://developers.google.com/web/updates/2017/09/sticky-headers

UPDATE - To specify my need:

The class "sticky-top" assigns position:sticky to an element. In my specific case, I desire to assign an extra class to a DIV only when the DIV is stuck at the top. This could be used, for instance, to apply a shadow effect to the element but exclusively when it's "stuck" at the top. Thus, I require class B solely under these circumstances.

Answer №1

Hi there! I recently shared a Medium article on this topic. It may or may not directly relate to your situation, but I recommend taking a few minutes to give it a read.

Check out the article here

The main idea behind this technique is to use an element as a cover for the shadow. As the user scrolls, the cover moves up to reveal the shadow behind it.

You can see this technique in action with this JSFiddle link: View the demo here

.shadow {
  position: sticky;
  top: 200px;
  width: 297px;
  box-shadow: 0px 0.5px 0.5px 1.5px rgba(0,0,0,0.75);
}

.cover {
  position: absolute;
  background: white;
  width: 100%;
  height: 3px;
}

Answer №2

My solution can handle any top/bottom offset you specify. It checks for the elements you want and determines if the stickiness threshold has been reached.

If scroll/resize events occur too frequently, you can use the commented-out version below with a debounce to check less often.

Note: This solution assumes that your top/bottom CSS values are in pixels, as other units may not work properly here.

$(() => {
  const stuckClass = 'is-stuck';
  const $stickyTopElements = $('.sticky-top');
  const $stickyBottomElements = $('.sticky-bottom');

  const determineSticky = () => {
    $stickyTopElements.each((i, el) => {
      const $el = $(el);
      const stickPoint = parseInt($el.css('top'), 10);
      const currTop = el.getBoundingClientRect().top;
      const isStuck = currTop <= stickPoint;
      $el.toggleClass(stuckClass, isStuck);
    });

    $stickyBottomElements.each((i, el) => {
      const $el = $(el);
      const stickPoint = parseInt($el.css('bottom'), 10);
      const currBottom = el.getBoundingClientRect().bottom;
      const isStuck = currBottom + stickPoint >= window.innerHeight;
      $el.toggleClass(stuckClass, isStuck);
    });
  };

  //run immediately
  determineSticky();

  //Run when the browser is resized or scrolled
  //Uncomment below to run less frequently with a debounce
  //let debounce = null;
  $(window).on('resize scroll', () => {
    //clearTimeout(debounce);
    //debounce = setTimeout(determineSticky, 100);

    determineSticky();
  });

});
.sticky-top,
.sticky-bottom {
  position: sticky;
  z-index: 1000;
  padding: 10px;
  border: 1px solid #CCC;
  background-color: #FFF;
  transition: all 300ms;
}

.sticky-top {
  top: 40px;
}

.sticky-bottom {
  bottom: 40px;
}

.is-stuck {
  background: blue;
  color: white;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<p>some text</p>
<p>some text</p>
<p>some text</p>
<div class="sticky-top">
  Sticky to the top!
</div>

<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>
<div class="sticky-bottom">
  Sticky to the bottom!
</div>

<p>some text</p>
<p>some text</p>
<p>some text</p>
<p>some text</p>

Answer №3

To determine this, the only option is to calculate the position of the div while scrolling.

$('#wrapper').scroll(function() {
var wrapperTop = $(this).offset().top;
var headerTop = $('#header').offset().top;
if (wrapperTop < headerTop)
  $('#header').css('background','grey');
  else
  $('#header').css('background','red');
});
#wrapper {
  width: 200px;
  height: 200px;
  border: 1px solid black;
  overflow-y: scroll;
}

#header {
  height: 50px;
  background: grey;
  top: -1px;
  position: sticky;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
  <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</div>
  <div id="header">HEADER TEXT</div>
  <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>

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

How can we display a fallback image if the Iframe is unable to load the resource at src in AngularJs?

In one of my JSP pages, I am utilizing an iframe and I want to set an external address as the src of this iframe. Typically, everything works fine. However, in cases where the external source is unavailable, I want to display a static image instead. I&apos ...

What is the best way to retrieve multiple model values from a single selection in AngularJS?

I recently started learning AngularJS and have a basic question to ask. I have a select box that allows users to choose a country from a list of countries. Currently, when a country is selected, only the country code is stored in the model. However, I woul ...

Exploring ways to incorporate or eliminate animations on mobile devices using html/css

Is it possible to control animations on different devices using media queries? For example, can you show an animation only on mobile devices while hiding it on desktop or laptop? Conversely, is there a way to add an animation specifically for mobile device ...

Contrasting importing CSS directly in index.html versus using styleUrls in Angular 5

My landing page and dashboard components have different CSS styling, causing one of them to not function properly depending on the CSS. I tried removing these two lines from index.html: <link href="./assets/css/bootstrap.min.css" rel="stylesheet" /&g ...

How to Maintain SASS Code Efficiency with Media Queries

How can I avoid repeating myself in my CSS code when using two different media queries for phones and tablets that require the same exact styling? $mobile-portrait: "only screen and (max-width: 680px)"; $tablet-portrait: "only screen and (min-device-wid ...

Tips for invoking a function to automatically load elements on a jQuery mobile website

I am looking to keep my navbar HTML markup in a centralized location for easy editing. Currently, the body content of my index.html file appears like this: <div data-role="page" id="SomePage"> <div data-role="header"> <h1>Thi ...

What could be the reason for my navbar menu getting cropped?

I have been tasked with making modifications to a website that was created using Bootstrap v3.3.7. The site includes a navbar (HTML provided below) that appears fine. However, I needed to add a dropdown item to the navbar, which I did by following the guid ...

Tips for creating a custom Menu with content overflow in a single direction

What is the goal of this task? I have developed a custom Menu in my application with 8 options. There is a need to dynamically disable certain menu options based on specific conditions (e.g. disabling the last 4 options). When a user hovers over a disable ...

combining: enhancing the value of the background-image property

Here is a mixin that I would like to modify: .a () {background-image: url(one.png);} I want to create a new class .b which inherits properties from .a, but also includes an additional background image layer, like this: .b { .a; ...

The React modal refuses to disappear, stubbornly clinging to the original component it sprang from

Hey there, I'm a beginner in learning React and I'm encountering an issue with my popup modal component. Even after showing the modal, I can still interact with and click on the main UI elements. Can anyone assist me with this problem? https://i ...

Exploring the integration of Construct 3 objects with ReactJs

Although I am well-acquainted with Construct 3 platform, I now have an interest in website development. Specifically, I would like to incorporate a character-like object into my web project that moves similar to a game character. While I know how to achiev ...

What is the method for aligning inline-block text to the right after a line break?

I am currently encountering a challenge in developing a directory tree using <ul> element, particularly when the text of an item exceeds the width of the container. As I am utilizing the antd React library for this project, my options are somewhat l ...

A CSS rule to display a nested list on the left-hand side

I created a menu that you can view here. When hovering over "tanfa demo example," the sublist appears on the right side. The issue I'm facing is that my menu is positioned all the way to the right, which means the sublist also appears on the extreme ...

Desktop displays do not show images, only mobile devices

My website displays multiple retailer images as affiliate links. I am facing an issue where the images are not visible on desktop for some users, even though I can see them on my end. I have tried clearing cache, cookies, and using different browsers, but ...

Arranging CSS text in a parallel format and aligning it vertically

I am working on a layout with two columns of text placed side by side, where one column is right aligned and the other is left aligned. Below is my current code: .alignleft { float: left; } .alignright { float: right; } .list-unstyled { padding ...

What is the best way to adjust the bootstrap column size using variables and decide when to insert a new row dynamically?

I am struggling to dynamically change the number of columns in a row based on the already sorted array. I want the layout to look like the example at the bottom, with Comedies spanning two rows, Action spanning three, and Horror only one row. However, I ca ...

Navigating between divs with a 100% height using up and down movements

I am working on a website that is structured into different sections using divs with shared classes but unique IDs. Each div is set to take up 100% of the viewport height. To navigate between these sections, I want to provide Up/Down arrow buttons for user ...

Efficiently reducing the size of a CSS selector string with javascript

Is there a library that already performs this function? I've only been able to find online tools. The reason I am interested in accomplishing this task using JavaScript is because I need to ensure that the strings a > b, a and a> b,a are conside ...

How can I move one of the multiple input fields to the top right side?

I am facing an issue and need some assistance. I have created a page with multiple font controls, but in my prototype design, there is a field on the right side where the inputs are positioned at the top and on the right. How can I achieve this? I have cr ...

CSS - With the abundance of positioning methods available, determining the right approach can be quite a puzzle

As I delved into web development, my fascination with positioning grew. In the beginning, my novice websites were structured like this: <body> <h1> Welcome to my website. </h1> <br> <br> <br> <br> <br> ...