Search code examples
javascriptcssvue.jscss-positionvuex

CSS position: sticky behaves differently on scroll up and scroll down


In my Vue CLI app, I'm applying position: sticky on a component. On scroll down, half of the component is incorrectly hidden under the top of the browser, on scroll up however, it works as intended.

Notice how the component appears differently on scroll up vs scroll down. It also happens on my phone (Galaxy S8).

Here is the relevant code:

//template
<Stepper :class="{ fixed: hasScrolled }" />

//script
methods: {
  methods: {
    scroll() {
      window.onscroll = () => {
        if (window.pageYOffset > 25) {
          this.$store.dispatch("updateHasScrolled", true);
        }
        if (window.pageYOffset < 25) {
          this.$store.dispatch("updateHasScrolled", false);
        }
      };
    }
  },
  computed: {
    hasScrolled() {
      return this.$store.getters.getHasScrolled;
    }
  }

//style
@media (max-width: 600px) {
  .fixed {
    position: sticky;
    position: -webkit-sticky;
    z-index: 10;
    width: 100%;
    top: 0;
    left: 0;
  }
}

The repo is hosted here.


Solution

  • I noticed through logging window.pageYOffset to the console, that instead of it having the value of 0 at the top of the page, instead, it received the value of 0 after scrolling a little down the page. It's almost as if it was treating the top of the window as some arbitrary number of pixels further down.

    I still don't know why it was doing that, but I managed to fix this inadvertently by fixing another bug.

    I had a button that had a margin that was pushing it out of its container, causing overflow. I removed the margin, and somehow window.pageYOffset started behaving as expected, with the value 0 being at the top of the page. Weird one, but glad its resolved.