Home > Mobile >  Position sticky isn't working even without any parent having overflow hidden
Position sticky isn't working even without any parent having overflow hidden

Time:12-30

// observer for feature section
let featuresSection = document.querySelector('#featuresSection');

let callbackFeature = (items) => {
    items.forEach((item) => {
        if (item.isIntersecting) {
            item.target.classList.add("in-page");

        } else {

            item.target.classList.remove("in-page");

        }
    });
}
let observerFeature = new IntersectionObserver(callbackFeature, {
    threshold: 0.3
});
observerFeature.observe(featuresSection);
.features-section.in-page {
    position: -webkit-sticky;
    position: -moz-sticky;
    position: -ms-sticky;
    position: -o-sticky;

    position: sticky !important;
    top: 0 !important;
    background-color: red;
    display: block;
  }
  
   .features-img {
   width:100%
    object-fit: contain;
    transition: all 0.5s cubic-bezier(0.215, 0.61, 0.355, 1);
  }
<!-- Bootstrap CSS -->
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
      integrity="sha384-Vkoo8x4CGsO3 Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
      crossorigin="anonymous"
    />
<div ><div>

<section id="featuresSection" >
        <h2 >Newest set of Advanced Features</h2>
        <h3 >Achieve the impossible</h3>

        <div >
          <div >
            <img id="ftr-img-1"
              
              src="https://m.media-amazon.com/images/I/81LNgb-7FnL._AC_SX569_.jpg"
              alt=""
            />
            <img id="ftr-img-2"
              
              src="https://m.media-amazon.com/images/I/911Gc7IMlmL._AC_SX569_.jpg"
              alt=""
            />
            <img id="ftr-img-3"
              
              src="https://m.media-amazon.com/images/I/91z5KuonXrL._AC_SX569_.jpg"
              alt=""
            />
            <img id="ftr-img-4"
              
              src="https://m.media-amazon.com/images/I/81jYRL0oCSL._AC_SX679_.jpg"
              alt=""
            />
          </div>
          <div
            
          >
            <div >
              <h4>High Performance</h4>
              <p>
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit?
              </p>
            </div>
            <div >
              <h4>Long Lasting Battery</h4>
              <p>
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit?
              </p>
            </div>
          </div>

          <div
            
          >
            <div >
              <h4 >Titanium Case</h4>
              <p >
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit? Lorem ipsum dolor sit amet.
              </p>
            </div>
            <div >
              <h4 >New GPS Antenna</h4>
              <p >
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit? Lorem ipsum dolor sit amet.
              </p>
            </div>
          </div>
        </div>
      </section>

What could be the causes of a sticky element not working besides:

  • Having a parent element with any overflow:hidden
  • Not having set the top position to stick to
  • The sticky element being a flexbox or grid
  • Sticky property not having browser support

Because my element doesn't have any of those problems, I even checked for an overflow:hidden in the css both with CTRL F and with a script that checks for it in the console. Yet it doesn't stick to the top of the page. Thanks in advance.

This is the CSS for my section: Background red is for debugging and it works, but the sticky property doesn't work.

.features-section.in-page {
    position: -webkit-sticky;
    position: -moz-sticky;
    position: -ms-sticky;
    position: -o-sticky;

    position: sticky !important;
    top: 0 !important;
    background-color: red;
    display: block;
  }

And this is my section itself:

<section id="featuresSection" >
        <h2 >Newest set of Advanced Features</h2>
        <h3 >Achieve the impossible</h3>

        <div >
          <div >
            <img id="ftr-img-1"
              
              src="https://m.media-amazon.com/images/I/81LNgb-7FnL._AC_SX569_.jpg"
              alt=""
            />
            <img id="ftr-img-2"
              
              src="https://m.media-amazon.com/images/I/911Gc7IMlmL._AC_SX569_.jpg"
              alt=""
            />
            <img id="ftr-img-3"
              
              src="https://m.media-amazon.com/images/I/91z5KuonXrL._AC_SX569_.jpg"
              alt=""
            />
            <img id="ftr-img-4"
              
              src="https://m.media-amazon.com/images/I/81jYRL0oCSL._AC_SX679_.jpg"
              alt=""
            />
          </div>
          <div
            
          >
            <div >
              <h4>High Performance</h4>
              <p>
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit?
              </p>
            </div>
            <div >
              <h4>Long Lasting Battery</h4>
              <p>
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit?
              </p>
            </div>
          </div>

          <div
            
          >
            <div >
              <h4 >Titanium Case</h4>
              <p >
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit? Lorem ipsum dolor sit amet.
              </p>
            </div>
            <div >
              <h4 >New GPS Antenna</h4>
              <p >
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit? Lorem ipsum dolor sit amet.
              </p>
            </div>
          </div>
        </div>
      </section> 

And this is my JS that uses an Intersection observer to add the position sticky and also a background color red for debugging:

// observer for feature section
let featuresSection = document.querySelector('#featuresSection');

let callbackFeature = (items) => {
    items.forEach((item) => {
        if (item.isIntersecting) {
            item.target.classList.add("in-page");

        } else {

            item.target.classList.remove("in-page");

        }
    });
}
let observerFeature = new IntersectionObserver(callbackFeature, {
    threshold: 0.3
});
observerFeature.observe(featuresSection);

CodePudding user response:

Sticky shall not fill its entire parent to be visually sticky. once it reaches the bottom of its closest positionned parent, it will move with it and will not overflow. If another sticky element comes in the way, it also moves away.

Your example with some elements before and after let you see that it does stick:

// observer for feature section
let featuresSection = document.querySelector('#featuresSection');

let callbackFeature = (items) => {
  items.forEach((item) => {
    if (item.isIntersecting) {
      item.target.classList.add("in-page");

    } else {

      item.target.classList.remove("in-page");

    }
  });
}
let observerFeature = new IntersectionObserver(callbackFeature, {
  threshold: 0.2
});
observerFeature.observe(featuresSection);
.features-section.in-page {
  position: sticky;
  top: 0;
  background-color: red;
}

.features-img {
  width: 100% object-fit: contain;
  transition: all 0.5s cubic-bezier(0.215, 0.61, 0.355, 1);
}
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3 Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous" />
<div >
  <div>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <section id="featuresSection" >
      <h2 >Newest set of Advanced Features</h2>
      <h3 >Achieve the impossible</h3>

      <div >
        <div >
          <img id="ftr-img-1"  src="https://m.media-amazon.com/images/I/81LNgb-7FnL._AC_SX569_.jpg" alt="" />
          <img id="ftr-img-2"  src="https://m.media-amazon.com/images/I/911Gc7IMlmL._AC_SX569_.jpg" alt="" />
          <img id="ftr-img-3"  src="https://m.media-amazon.com/images/I/91z5KuonXrL._AC_SX569_.jpg" alt="" />
          <img id="ftr-img-4"  src="https://m.media-amazon.com/images/I/81jYRL0oCSL._AC_SX679_.jpg" alt="" />
        </div>
        <div >
          <div >
            <h4>High Performance</h4>
            <p>
              Lorem ipsum dolor sit, amet consectetur adipisicing elit. Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati laudantium suscipit?
            </p>
          </div>
          <div >
            <h4>Long Lasting Battery</h4>
            <p>
              Lorem ipsum dolor sit, amet consectetur adipisicing elit. Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati laudantium suscipit?
            </p>
          </div>
        </div>

        <div >
          <div >
            <h4 >Titanium Case</h4>
            <p >
              Lorem ipsum dolor sit, amet consectetur adipisicing elit. Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati laudantium suscipit? Lorem ipsum dolor sit amet.
            </p>
          </div>
          <div >
            <h4 >New GPS Antenna</h4>
            <p >
              Lorem ipsum dolor sit, amet consectetur adipisicing elit. Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati laudantium suscipit? Lorem ipsum dolor sit amet.
            </p>
          </div>
        </div>
      </div>
    </section>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>
    <p>give it some space</p>

But you probably only want the titles to stick

Let's do this and see it working ;)

// observer for feature section
let featuresSection = document.querySelector('#featuresSection');

let callbackFeature = (items) => {
  items.forEach((item) => {
    if (item.isIntersecting) {
      item.target.classList.add("in-page");

    } else {

      item.target.classList.remove("in-page");

    }
  });
}
let observerFeature = new IntersectionObserver(callbackFeature, {
  threshold: 0.3
});
observerFeature.observe(featuresSection);
.features-section.in-page {
  position: sticky;
  z-index: 1;
  top: 0;
  background-color: red;
}

.features-img {
  width: 100% object-fit: contain;
  transition: all 0.5s cubic-bezier(0.215, 0.61, 0.355, 1);
}
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3 Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous" />
<div >
  <div>
  <p>Would it be anything here before?</p>
    <section >
      <hgroup id="featuresSection" >
        <h2 >Newest set of Advanced Features</h2>
        <h3 >Achieve the impossible</h3>
      </hgroup>
      <div >
        <div >
          <img id="ftr-img-1"  src="https://m.media-amazon.com/images/I/81LNgb-7FnL._AC_SX569_.jpg" alt="" />
          <img id="ftr-img-2"  src="https://m.media-amazon.com/images/I/911Gc7IMlmL._AC_SX569_.jpg" alt="" />
          <img id="ftr-img-3"  src="https://m.media-amazon.com/images/I/91z5KuonXrL._AC_SX569_.jpg" alt="" />
          <img id="ftr-img-4"  src="https://m.media-amazon.com/images/I/81jYRL0oCSL._AC_SX679_.jpg" alt="" />
        </div>
        <div >
          <div >
            <h4>High Performance</h4>
            <p>
              Lorem ipsum dolor sit, amet consectetur adipisicing elit. Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati laudantium suscipit?
            </p>
          </div>
          <div >
            <h4>Long Lasting Battery</h4>
            <p>
              Lorem ipsum dolor sit, amet consectetur adipisicing elit. Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati laudantium suscipit?
            </p>
          </div>
        </div>

        <div >
          <div >
            <h4 >Titanium Case</h4>
            <p >
              Lorem ipsum dolor sit, amet consectetur adipisicing elit. Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati laudantium suscipit? Lorem ipsum dolor sit amet.
            </p>
          </div>
          <div >
            <h4 >New GPS Antenna</h4>
            <p >
              Lorem ipsum dolor sit, amet consectetur adipisicing elit. Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati laudantium suscipit? Lorem ipsum dolor sit amet.
            </p>
          </div>
        </div>
      </div>
    </section>

Notes that prefix are no longer needed for nowdays browsers. !important is also not necessary, but z-index can be handy :).

CodePudding user response:

Not sure if this is what you wanted - but you don't need the intersection observer (though I applaud the use of these newer DOM methods).... If you are simply looking for the header elements to stick to the top pf the page on scrolling - then you need to apply the position-sticky to them - not the entire section.

For simplicity - I wrapped the h2 and 3 in a div - and put the position sticky onto that. Note that you also need the z-index to ensure that the content scrolls under the stuck header content.

I removed the intersection observer to demonstrate the new div and the style changes.

.header-wrapper {
    position: -webkit-sticky;
    position: -moz-sticky;
    position: -ms-sticky;
    position: -o-sticky;

    position: sticky;
    top: 0;
    background-color: red;
    display: block;
    z-index: 99
  }
  
   .features-img {
   width:100%
    object-fit: contain;
    transition: all 0.5s cubic-bezier(0.215, 0.61, 0.355, 1);
  }
<!-- Bootstrap CSS -->
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
      integrity="sha384-Vkoo8x4CGsO3 Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
      crossorigin="anonymous"
    />
<div ><div>

<section id="featuresSection" >
    <div >
        <h2 >Newest set of Advanced Features</h2>
        <h3 >Achieve the impossible</h3>
     </div>

        <div >
          <div >
            <img id="ftr-img-1"
              
              src="https://m.media-amazon.com/images/I/81LNgb-7FnL._AC_SX569_.jpg"
              alt=""
            />
            <img id="ftr-img-2"
              
              src="https://m.media-amazon.com/images/I/911Gc7IMlmL._AC_SX569_.jpg"
              alt=""
            />
            <img id="ftr-img-3"
              
              src="https://m.media-amazon.com/images/I/91z5KuonXrL._AC_SX569_.jpg"
              alt=""
            />
            <img id="ftr-img-4"
              
              src="https://m.media-amazon.com/images/I/81jYRL0oCSL._AC_SX679_.jpg"
              alt=""
            />
          </div>
          <div
            
          >
            <div >
              <h4>High Performance</h4>
              <p>
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit?
              </p>
            </div>
            <div >
              <h4>Long Lasting Battery</h4>
              <p>
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit?
              </p>
            </div>
          </div>

          <div
            
          >
            <div >
              <h4 >Titanium Case</h4>
              <p >
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit? Lorem ipsum dolor sit amet.
              </p>
            </div>
            <div >
              <h4 >New GPS Antenna</h4>
              <p >
                Lorem ipsum dolor sit, amet consectetur adipisicing elit.
                Ducimus facilis aut totam amet veniam ab. Eius optio obcaecati
                laudantium suscipit? Lorem ipsum dolor sit amet.
              </p>
            </div>
          </div>
        </div>
      </section>

  • Related