Skip to content

Lazy Background Images ​

v-lazy-img is a directive for setting background-image on any element after it enters the viewport. Use it when you can't use the <VImage> component — CSS backgrounds, third-party wrappers, etc.

vue
<!-- Simple string -->
<div v-lazy-img="'/background.jpg'" class="hero" />

<!-- Object with options -->
<div
  v-lazy-img="{
    src: '/background.jpg',
    placeholder: 'data:image/jpeg;base64,...',
    rootMargin: '100px',
    onLoad: () => console.log('loaded'),
    onError: (e) => console.error(e),
  }"
  class="hero"
/>

Options ​

src ​

string, required. URL of the background image.

placeholder ​

string, optional. Base64 or URL shown immediately; replaced on load.

rootMargin ​

string · default: "200px". IO rootMargin.

threshold ​

number · default: 0. IO threshold.

onLoad ​

() => void, optional. Called when the image finishes loading.

onError ​

(e: Event) => void, optional. Called when the image fails to load.

Placeholders from the manifest ​

With no placeholder of its own, the directive looks up its src in the placeholders manifest registered for the app and paints the entry's decoded blur and dominant color on the element as soon as it is mounted — before the image is near the viewport. The color is cleared once the image has loaded. An explicit placeholder always wins, and an image that has no entry is left as it was.

Behaviour ​

  1. On mount — gets a pooled IntersectionObserver (shared with useLazyLoad/useImage/<VImage>/useBackgroundImage, keyed by rootMargin/threshold) and starts watching the element
  2. When the element enters the viewport — if placeholder is set it is applied immediately as background-image
  3. A new Image object loads src in the background
  4. On load — background-image is updated to src; onLoad is called
  5. On error — onError is called; background-image stays as the placeholder (if any)
  6. On unmount — the observer is disconnected
  7. On binding update — the observer is recreated with the new options

Registering the directive manually ​

The directive is registered automatically with VImageKitPlugin. To register it in a single component:

vue
<script setup lang="ts">
import { vLazyImg } from '@macrulez/vue-image-kit'
</script>

<template>
  <div v-lazy-img="'/bg.jpg'" style="width:100%;height:400px" />
</template>

Or globally without the plugin:

ts
import { vLazyImg } from '@macrulez/vue-image-kit'

app.directive('lazy-img', vLazyImg)

Example — card with lazy background ​

vue
<script setup lang="ts">
import { vLazyImg } from '@macrulez/vue-image-kit'

const cards = [
  { id: 1, bg: '/card-1.jpg', placeholder: 'data:image/jpeg;base64,/9j/...' },
  { id: 2, bg: '/card-2.jpg', placeholder: 'data:image/jpeg;base64,/9j/...' },
]
</script>

<template>
  <div
    v-for="card in cards"
    :key="card.id"
    v-lazy-img="{ src: card.bg, placeholder: card.placeholder }"
    class="card"
  />
</template>

<style scoped>
.card {
  width: 300px;
  height: 200px;
  background-size: cover;
  background-position: center;
  border-radius: 12px;
}
</style>

Need srcset/image-set() for responsive backgrounds too? See Responsive Lazy Backgrounds — the composable counterpart.