I have created a page where each section fills the entire screen and is styled using CSS position: sticky;
to create a cool layered effect. Check it out here:
https://codesandbox.io/s/ecstatic-khayyam-cgql1?fontsize=14&hidenavigation=1&theme=dark
Everything works great so far.
The issue arises when navigating between these sections with JavaScript. When trying to use the menu, you'll notice that the links work on sections that are not yet "sticky", but you can't navigate back up the page.
I suspect the problem lies in el.getBoundingClientRect()
, which causes the top value of a sticky element to always be zero once it becomes sticky.
To navigate around this issue, I'm currently using a small library called Jump.js
. However, even with vanilla JS, the problem remains due to the calculations involved when an element becomes sticky.
Is there a way to determine the original position of each section before it became sticky? This would allow me to manually set the scroll position for smoother navigation.
Although I'm working with Vue.js, the core issue pertains to CSS and JS interactions, unaffected by the framework.
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>
If anyone has any solutions that could help resolve the auto-scrolling issues in both directions, I would greatly appreciate your insights. Thank you!