npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

chameleon-backgrounds

v3.1.3

Published

A zero-dependency JavaScript library to dynamically load background images with elegant fade-in transitions and slideshow support.

Downloads

1,256

Readme

ChameleonBackgrounds

A zero-dependency JavaScript library to dynamically load background images with elegant fade-in transitions and slideshow support.

v3.0 — Added responsive srcset, seamless crossfading, lazy-loading, and play/pause API. v2.0 — Fully rewritten from scratch. No jQuery required.


Why?

Large background images slow down initial page loads. ChameleonBackgrounds defers loading these images and reveals them with a smooth CSS transition once they're fully downloaded — no layout shifts, no flicker.

Features

  • 🎯 Zero dependencies — no jQuery, no frameworks
  • 🖼️ Responsive images — native srcset and sizes support
  • 🎠 Slider mode with configurable duration and looping
  • Crossfade & Solid transitions
  • Lazy loading via IntersectionObserver
  • Accessibility — respects prefers-reduced-motion
  • 🎨 Overlay support with color, pattern images, and minimum opacity
  • 🎛️ Play / Pause API for manual control
  • 🧹 destroy() method for clean teardown
  • 📦 ES Module + UMD dual distribution
  • 🔄 Backward compatible with v1 snake_case option names

Installation

Package Managers (npm / yarn / bun)

# npm
npm install chameleon-backgrounds

# yarn
yarn add chameleon-backgrounds

# bun
bun add chameleon-backgrounds

CDN / Script Tag

<script src="dist/chameleon-backgrounds.js"></script>

ES Module

import ChameleonBackgrounds from 'chameleon-backgrounds';

Quick Start

Single Background

<script src="dist/chameleon-backgrounds.js"></script>
<script>
  const bg = new ChameleonBackgrounds({
    element: 'body',
    type: 'single',
    src: './img/chameleon.jpg',
    overlayColor: '#0f1e25',
    overlayImage: './img/transparent-tile.png', // optional
    minOverlay: 0.5,                            // optional, default: 0
    transitionDuration: 2000
  });
</script>

Slider / Slideshow

<div id="hero"></div>

<script src="dist/chameleon-backgrounds.js"></script>
<script>
  const bg = new ChameleonBackgrounds({
    element: '#hero',
    type: 'slider',
    src: [
      './img/image1.jpg',
      './img/image2.jpg',
      './img/image3.jpg'
    ],
    overlayColor: '#656946',
    overlayImage: './img/transparent-tile.png', // optional
    minOverlay: 0.6,                            // optional
    transitionDuration: 3000,
    sliderDuration: 4000,
    sliderLoop: true
  });
</script>

ES Module Usage

import ChameleonBackgrounds from 'chameleon-backgrounds';

const bg = new ChameleonBackgrounds({
  element: '#hero',
  type: 'single',
  src: '/images/hero.jpg',
  overlayColor: '#1a1a2e',
  transitionDuration: 1500
});

// Clean up when done
bg.destroy();

Responsive Images

You can provide an object containing url, srcset, and sizes properties to leverage native browser responsive image support. This works perfectly for both type: 'single' and type: 'slider'.

// Example using responsive images in a slider
const bg = new ChameleonBackgrounds({
  element: '#hero',
  type: 'slider',
  src: [
    {
      url: './img/slide1.jpg',
      srcset: './img/slide1-mobile.jpg 480w, ./img/slide1.jpg 1920w',
      sizes: '100vw'
    },
    {
      url: './img/slide2.jpg',
      srcset: './img/slide2-mobile.jpg 480w, ./img/slide2.jpg 1920w',
      sizes: '100vw'
    }
  ],
  transitionDuration: 1500
});

Options

| Option | Type | Default | Required | Description | |---|---|---|---|---| | element | string \| HTMLElement | 'body' | yes | CSS selector or DOM element to attach to | | type | 'single' \| 'slider' | 'single' | yes | Background mode | | src | string \| array \| object | '' | yes | Image URL, array of URLs, or config object {url, srcset, sizes} | | overlayColor | string | '#0f1e25' | yes | Overlay color (hex, rgb, rgba, hsl) | | overlayImage | string \| null | null | no | Overlay pattern image URL | | minOverlay | number | 0 | no | Minimum overlay opacity after fade (0–1) | | transitionDuration | number | 2000 | yes | Fade duration in milliseconds | | sliderDuration | number | 8000 | slider only | Time each slide is shown (ms) | | sliderLoop | boolean | false | slider only | Restart slider after last slide | | fetchPriority | string | 'auto' | no | Network priority for the initial image load. | | lazyLoad | boolean | true | no | Defer loading until element intersects viewport | | transitionMode | 'solid' \| 'crossfade' | 'solid' | no | Transition effect. 'solid' fades to overlay color, 'crossfade' fades between images | | respectReducedMotion | boolean | false | no | Auto-pause slider if user's OS has animations disabled |

Legacy Option Names

For backward compatibility, v1 snake_case option names are still supported:

| v1 (snake_case) | v2 (camelCase) | |---|---| | transition_duration | transitionDuration | | slider_duration | sliderDuration | | slider_loop | sliderLoop | | min_overlay | minOverlay | | overlay_color | overlayColor | | overlay_image | overlayImage | | lazy_load | lazyLoad | | transition_mode | transitionMode | | respect_reduced_motion | respectReducedMotion |


Optimize for Largest Contentful Paint (LCP)

To get a great LCP score on PageSpeed Insights, you should set fetchPriority: 'high' on your main above-the-fold background instance.

Additionally, because browsers cannot discover JavaScript-loaded images in the initial HTML document parse, you should add a preload link to your <head> for the hero image:

<link rel="preload" as="image" href="path/to/hero.jpg" fetchpriority="high">

SSR Hydration (Zero CLS)

If you want to completely eliminate layout shifts (CLS) and load the background instantly, you can hardcode the initial state into your HTML. The script will automatically detect this and "hydrate" the DOM without re-rendering it.

1. Apply inline styles to your target element (e.g., <body class="cbg-host">) Include your initial background image, overlay properties, and cbg-host class.

2. Wrap your content in a <div class="cbg-inner">

3. Add the <div class="cbg-loader"> right after it

Example:

<!-- 1. Setup the host element with the background and CSS variables -->
<body class="cbg-host" style="background-image: url('path/to/image.jpg'); background-size: cover; background-position: center; background-repeat: no-repeat; --cbg-duration: 2s; --cbg-overlay-color: #0f1e25; --cbg-min-overlay: 0.5;">
  
  <!-- 2. Wrap your page content -->
  <div class="cbg-inner">
     <h1>My Website</h1>
     <p>Content goes here...</p>
  </div>
  
  <!-- 3. Add the loader div at the very bottom of the host element -->
  <div class="cbg-loader" style="opacity: 0.5;"></div>

</body>

When ChameleonBackgrounds initializes on this element, it will instantly take over without causing any flickers, repaints, or layout shifts!


API

new ChameleonBackgrounds(options)

Creates a new instance and immediately begins loading.

.destroy()

Stops any running slider, removes all injected DOM and styles, and restores the target element to its original state.

.play()

Resumes a paused slider.

.pause()

Pauses an active slider.

.getOptions() / .options (ESM)

Returns a read-only copy of the resolved options.

.reloadOptions(newOptions)

Update options on the fly without destroying the instance. For example, you can change the transition duration or even convert a single background into a slider dynamically:

bg.reloadOptions({
  type: 'slider',
  src: [
    './img/slide1.jpg',
    './img/slide2.jpg'
  ],
  transitionDuration: 5000,
  overlayColor: '#ff0000'
});
// To apply the updated options, simply reload the background
bg.reloadBackground();

Migration from v1

  1. Remove jQuery — ChameleonBackgrounds v2 uses native DOM APIs.
  2. Rename options (optional) — snake_case names still work, but camelCase is now preferred.
  3. Use newnew ChameleonBackgrounds(options) works identically to v1.
  4. Clean up — Call .destroy() when removing the background (new in v2).
- <script src="jquery.min.js"></script>
- <script src="chameleonbackgrounds.js"></script>
+ <script src="dist/chameleon-backgrounds.js"></script>

  <script>
-   var options = {
+   const options = {
      element: 'body',
      type: 'single',
      src: './img/chameleon.jpg',
      overlayColor: '#0f1e25',
-     transition_duration: 2000
+     transitionDuration: 2000
    };

-   background = new ChameleonBackgrounds(options);
+   const background = new ChameleonBackgrounds(options);
  </script>

Tips

  • Transparent patterns work great as overlayImage — combine with overlayColor and minOverlay for cohesive designs across different background images.
  • Find awesome transparent patterns at transparenttextures.com.

License

MIT © Lennart van Ballegoij