A necessidade de position: sticky existia há anos antes de ser implementada nativamente, e posso me gabar de tê-la implementado com JavaScript e scroll eventos por muito tempo. Por fim, conseguimos position: stickye ele funciona bem do ponto de vista visual, mas eu queria saber como podemos determinar quando o elemento foi realmente fixado devido à rolagem.

Podemos determinar se um elemento se tornou fixo graças à função API IntersectionObserver!

Fixar um elemento na parte superior de seu contêiner é tão fácil quanto uma diretiva CSS:

.myElement {
  position: sticky;
}

A questão ainda permanece sobre como podemos detectar que um elemento está sendo fixado. O ideal seria que houvesse um :stuck que poderíamos usar, mas, em vez disso, o melhor que podemos fazer é aplicar uma classe CSS quando o elemento se torna fixo usando um truque de CSS e alguma mágica de JavaScript:

.myElement {
  position: sticky;
  /* use "top" to provide threshold for hitting top of parent */
  top: -1px;
}

.is-pinned {
  color: red;
}
const el = document.querySelector(".myElement")
const observer = new IntersectionObserver( 
  ([e]) => e.target.classList.toggle("is-pinned", e.intersectionRatio 



As soon as myElement becomes stuck or unstuck, the is-pinned class is applied or removed. Check out this demo:

See the Pen WNwVXKx by David Walsh (@darkwing) on CodePen.

While there's not too much JavaScript involved, I hope we eventually get a CSS pseudo-class for this. Something like :sticky, :stuck, or :pinned seems as reasonable as :hover and :focus do.