Vue Sticky Directive

0.0.10 · maintenance · verified Sun Apr 19

This package provides a Vue.js directive, `v-sticky`, designed to make elements "sticky" within their designated container, mimicking the CSS `position: sticky` behavior. It enables configurable sticky effects through various attributes such as `sticky-offset` (allowing top and bottom breakpoints), `sticky-side` (to specify sticking to the top, bottom, or both), and `sticky-z-index` for layer control. Additionally, it offers an `on-stick` callback function that notifies when an element's sticky state changes. The current version, 0.0.10, indicates it's an early-stage project. While its release cadence isn't explicitly defined, the versioning suggests a more cautious release cycle, with the last known commit in May 2021. A key differentiator is its straightforward, directive-based API for Vue 2 applications, providing a robust solution for contextual sticky elements that can be scoped to a specific `sticky-container` rather than just the viewport.

Common errors

Warnings

Install

Imports

Quickstart

This example demonstrates how to globally register and use the `v-sticky` directive on a navigation bar. It shows how to define a `sticky-container`, set `sticky-offset` and `sticky-z-index`, and utilize the `on-stick` callback to react to the element's sticky state changes, applying a class when stuck. This code requires a Vue 2 environment.

<template>
  <div id="app">
    <header>
      <h1>My Awesome Page</h1>
      <p>Scroll down to see the sticky navigation!</p>
    </header>
    <div class="content-wrapper" sticky-container>
      <nav v-sticky sticky-offset='{ top: 0 }' sticky-side="top" sticky-z-index="10" :on-stick="handleStickChange">
        <ul>
          <li><a href="#section1">Section 1</a></li>
          <li><a href="#section2">Section 2</a></li>
          <li><a href="#section3">Section 3</a></li>
        </ul>
      </nav>
      <main>
        <section id="section1">
          <h2>Section 1</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
          <p>...</p>
        </section>
        <section id="section2">
          <h2>Section 2</h2>
          <p>Another long section to demonstrate scrolling.</p>
          <p>...</p>
        </section>
        <section id="section3">
          <h2>Section 3</h2>
          <p>The final section. Keep scrolling!</p>
          <p>...</p>
        </section>
      </main>
    </div>
    <footer>
      <p>Page footer</p>
    </footer>
  </div>
</template>

<script>
import Vue from 'vue';
import Sticky from 'vue-sticky-directive';

Vue.use(Sticky); // Register globally

export default {
  name: 'App',
  data() {
    return {
      isSticked: false
    };
  },
  methods: {
    handleStickChange(state) {
      console.log('Sticky state changed:', state);
      this.isSticked = state.sticked;
    }
  }
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  margin-top: 60px;
}
header, footer {
  background: #f0f0f0;
  padding: 20px;
  text-align: center;
}
.content-wrapper {
  display: flex;
  min-height: 1500px; /* Make content scrollable */
}
nav {
  width: 200px;
  background: #e9e9e9;
  padding: 15px;
}
nav.is-sticky {
  background-color: #d0d0d0;
  box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}
main {
  flex-grow: 1;
  padding: 20px;
}
section {
  min-height: 500px;
  margin-bottom: 30px;
  border-bottom: 1px solid #eee;
}
</style>

view raw JSON →