Skip to content

Affix ​

Pins an element to the viewport when scrolling past it. Useful for sticky headers, toolbars, and floating actions.

Basic ​

The element becomes fixed when you scroll past it.

vue
<script setup>
import { VxAffix, VxButton } from 'veloxui'
</script>

<template>
  <VxAffix>
    <div class="toolbar">Sticky Toolbar</div>
  </VxAffix>
</template>

Offset ​

Set the distance from the viewport edge before the element sticks.

vue
<VxAffix :offset="120">
  <div>Sticks 120px from the top edge</div>
</VxAffix>

Bottom Position ​

Pin to the bottom of the viewport with position="bottom".

vue
<VxAffix position="bottom" :offset="40">
  <VxButton>Always at bottom</VxButton>
</VxAffix>

Shadow ​

Add shadow to show a drop shadow when fixed — great for sticky headers.

Shadow appears when fixed
vue
<VxAffix :offset="0" shadow>
  <header class="nav">My App Header</header>
</VxAffix>

Custom Fixed Class ​

Use fixed-class to apply custom classes when the element is pinned. Accepts strings, arrays, or objects.

vue
<VxAffix :offset="0" fixed-class="bg-white shadow-xl border-b">
  <nav>Navigation Bar</nav>
</VxAffix>

<!-- Or with object syntax -->
<VxAffix :offset="0" :fixed-class="{ 'is-pinned': true, 'elevated': true }">
  <nav>Navigation Bar</nav>
</VxAffix>

Disabled ​

Toggle the affix on and off with disabled.

vue
<script setup>
import { ref } from 'vue'
const disabled = ref(false)
</script>

<template>
  <VxSwitch v-model="disabled" />
  <VxAffix :disabled="disabled">
    <div>Toggle me</div>
  </VxAffix>
</template>

Boundary ​

Use boundary to stop the affix before it overlaps another element. Pass a CSS selector or HTMLElement. The affix slides up to avoid colliding with the boundary.

vue
<!-- Affix stops before reaching the footer -->
<VxAffix :offset="0" boundary="#page-footer">
  <aside>Sidebar Navigation</aside>
</VxAffix>

<footer id="page-footer">Footer content</footer>

Scoped Slot ​

The slot receives fixed to react to the pinned state.

vue
<VxAffix :offset="0" shadow>
  <template #default="{ fixed }">
    <header :class="{ 'border-b': fixed }">
      <h1>{{ fixed ? 'Pinned Header' : 'Normal Header' }}</h1>
    </header>
  </template>
</VxAffix>

Custom Target ​

Scope the affix within a scrollable container by passing a CSS selector or HTMLElement to target.

vue
<div id="scroll-area" style="height: 300px; overflow: auto;">
  <div style="height: 1000px; padding: 20px;">
    <VxAffix target="#scroll-area" :offset="0">
      <div>Sticks within the scroll container</div>
    </VxAffix>
  </div>
</div>

API ​

VxAffix Props ​

PropTypeDefaultDescription
offsetnumber0Distance from viewport edge (px)
position'top' | 'bottom''top'Pin to top or bottom
targetstring | HTMLElementwindowScroll container
z-indexnumber100z-index when fixed
disabledbooleanfalseDisable the affix
shadowbooleanfalseShow shadow when fixed
fixed-classstring | string[] | object—Class binding when fixed
boundarystring | HTMLElement—Stop before reaching this element

Events ​

EventPayloadDescription
changebooleanFixed state changed
scroll{ scrollTop, fixed }Scroll with current state

Slots ​

SlotPropsDescription
default{ fixed: boolean }Content to affix

Exposed ​

NameTypeDescription
update()functionRecalculate position
fixedRef<boolean>Current fixed state