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.

Behaviour

  1. On mount — creates an IntersectionObserver 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.