Quantcast
Channel: Active questions tagged html - Stack Overflow
Viewing all articles
Browse latest Browse all 72531

Getting back to a CSS position sticky element with JavaScript?

$
0
0

I have a page where all sections fill the entire screen and are positioned with CSS position: sticky; in order to achieve a layered effect. See here:

https://codesandbox.io/s/ecstatic-khayyam-cgql1?fontsize=14&hidenavigation=1&theme=dark

This all works great and as expected.

The problem comes however from navigating between these areas with JavaScript. If you try using the menu, you can see that the links will work on sections that we haven't fully gotten to yet (and therefore not "sticky") but does not allow you to "go back up" the page.

I believe this is an issue with el.getBoundingClientRect() once an element has become "sticky", its top value becomes essentially always zero.

Here I am using a small library called Jump.js to jump around but even in vanilla JS this issue would still be the same, as the problem is a result of the calculation from when the element becomes sticky.

Is there any way to find the original position for each section before it was sticky? At least that way I could navigate the user by setting the scroll position manually.

I am using Vue.js but that does not affect the issue at hand which is CSS and JS related.

App.vue

<template>
  <main id="app">
    <ul class="menu">
      <li @click="goTo('A')">Section A</li>
      <li @click="goTo('B')">Section B</li>
      <li @click="goTo('C')">Section C</li>
      <li @click="goTo('D')">Section D</li>
      <li @click="goTo('E')">Section E</li>
    </ul>
    <SectionItem id="A" color="red"/>
    <SectionItem id="B" color="green"/>
    <SectionItem id="C" color="blue"/>
    <SectionItem id="D" color="orange"/>
    <SectionItem id="E" color="purple"/>
  </main>
</template>

<script>
import jump from "jump.js";
import SectionItem from "./components/SectionItem.vue";

export default {
  name: "App",
  components: {
    SectionItem
  },
  methods: {
    goTo(id) {
      jump(`#${id}`, {
        duration: 300
      });
    }
  }
};
</script>

SectionItem.vue

<template>
  <div :id="id" class="SectionItem" :style="styles">
    <p>I am section item: {{ id }}</p>
  </div>
</template>

<script>
export default {
  name: "SectionItem",
  props: {
    id: {
      type: String,
      required: true
    },
    color: {
      type: String,
      required: true
    }
  },
  computed: {
    styles() {
      return {
        backgroundColor: this.color
      };
    }
  }
};
</script>

<style>
.SectionItem {
  position: sticky;
  top: 0;
  width: 100%;
  min-height: 100vh;
  padding: 20px;
  color: white;
  border: 10px solid white;
}
</style>

I'm looking for any reasonable solutions that get get the auto-scrolling to work in both directions. Many thanks for your time.


Viewing all articles
Browse latest Browse all 72531

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>