Pull to refresh

Another event for CSS position: sticky

CSSJavaScriptHTML

Have you ever wondered how to track when elements with positions: sticky become fixed? Eric Bidelman has an amazing post on this topic, go and read it now.


I've found some difficulties while using it in my project. Here they are:


  1. It breaks encapsulation. sticky-change event relates to header element, but you have to insert sentinels to header's parent (and make it position: relative).
  2. It involves lots of factors that should be consistent and their connection is not always obvious. For example you can't set --default-padding greater than 40px, which is top-sentinel's height.
  3. You can't track block in the middle of an article.

Let's try to improve it!


All of those issues reflect the same problem: Eric's solution is about tracking sticky's parent position, not sticky block itself. Let's improve this while keeping the original idea. How? We'll add sentinels to header itself and observe their intersection with container.


example


Here is how to do it:


  1. You need one sentinel for each sticky side you want to observe.
  2. Set first sentinel top property equals to header top but with reverse sign minus 1. For example if your header have top: 10px, then set sentinel header to -11px. You can use something like top: calc(-1px + -1 * var( -- header-sticky-top)) or just set -1px if you have header top equals to zero.
  3. Add other sentinels if needed.
  4. Observe sentinels intersection with container.
  5. You can say that header stuck if sentinel intersection record has isIntersecting = true, intersectionRatio = 0, and intersectionRect.top = rootBounds.top
  6. Same other sides, just watch bottom, left, or right instead of top.
  7. Don't forget to add visibility: hidden and pointer-events: none to sentinels.

Check out demo and sources here

Tags:position: stickycsslayout
Hubs: CSS JavaScript HTML
Total votes 14: ↑13 and ↓1 +12
Views2.4K

Popular right now

Frontend Developer (JS/jQuery/CSS/Webasyst)
from 100,000 ₽WebasystМоскваRemote job
HTML-верстальщик (Junior/Middle)
from 30,000 to 40,000 ₽Media WorksRemote job
JavaScript-разработчик
to 180,000 ₽MobilityРязань
Frontend разработчик в SocialJet
to 100,000 ₽2КурсRemote job
HTML-верстальщик
from 60,000 ₽Sborka ProjectRemote job