Download ChameleonBackgrounds.js

See the snippet below for basic usage

ChameleonBackgrounds was created by Lennart from WebLenn
I essentially created this plugin to withhold large background image files from the initial load. This would not only improve loading times but also meant that we could show the background image when it's actually fully loaded. Therefore I created a simple overlay that creates a fade-In effect by using the CSS transition-duration property.

Github NPM Yarn
  • JS
  • CSS
  • HTML
<script>
const options = {
element: 'body',
type: 'single',
src: './img/chameleon.webp',
overlayColor: '#0f1e25',
overlayImage: './img/transparent-tile.webp', /* Optional */
minOverlay: '0.5', /* Optional, Default='0'; */
transitionDuration: 2000
}

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

Create beautiful background "sliders" on any element

See the snippet below on how to create a "slider" like this

  • JS
  • CSS
  • HTML
<script>
const options = {
element: '#bckoverlay-sample',
type: 'slider',
src: [
'./img/image1.webp',
'./img/image2.webp',
],
overlayColor: '#656946',
overlayImage: './img/transparent-tile.webp', /* Optional */
minOverlay: '0.6', /* Optional, Default='0'; */
transitionDuration: 3000,
sliderDuration: 4000,
sliderLoop: true,
fetchPriority: 'high',
transitionMode: 'crossfade', /* New seamless crossfade! */
lazyLoad: true
}

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

Creating a "slider" like the one above is fairly easy, create a new option object and add in the source urls in a array.

Set all other required options and call the ChameleonBackgrounds object.
To see which options are required go here.

Want to reload a single background image on an event ?

  • JS
<script>
document.querySelector('#reloadBckgrd').addEventListener('click', function() {
const imgsrc = document.querySelector('.imgurl').value;
background.reloadBackground(imgsrc);
});
</script>

Want to update options dynamically on the fly?

You can update any option (like turning a single background into a slider, or changing the transition duration) by passing new options to reloadOptions(), and then simply calling reloadBackground() to apply them!

  • JS
<script>
document.querySelector('#reloadOptionsBtn').addEventListener('click', function() {
background.reloadOptions({
type: 'slider',
src: [
'./inc/img/samples/sample4.webp',
'./inc/img/samples/sample5.webp',
'./inc/img/samples/sample7.webp'
]
});
background.reloadBackground();
});
</script>

Really on any element ?
Yes!!! look at these awesome links/buttons =D

  • JS
  • CSS
  • HTML
<script>
const options = {
element: '.awesomeBtn.first',
type: 'slider',
src: [
'./img/image1.webp',
'./img/image2.webp',
],
overlayColor: '#656946',
overlayImage: './img/transparent-tile.webp', /* Optional */
minOverlay: '0.1', /* Optional, Default='0'; */
transitionDuration: 3000,
sliderDuration: 6000,
sliderLoop: true
}

const awesomeBtn1 = new ChameleonBackgrounds(options);
</script>

Responsive image demo

Use the powerful srcset and sizes attributes to load optimized images for different screen sizes and resolutions.

Note: The optimal image is evaluated at the exact moment of loading to minimize network requests. If you are resizing your browser to test it, please refresh the page to see the new size!

  • JS
  • CSS
  • HTML
<script>
const options = {
element: '#responsive-hero',
type: 'single',
src: {
url: './inc/img/samples/sample4.webp', /* Fallback */
srcset: './inc/img/samples/sample7.webp 480w, ./inc/img/samples/sample5.webp 1080w, ./inc/img/samples/sample4.webp 1920w, ./inc/img/samples/sample3.webp 2560w',
sizes: '100vw'
},
overlayColor: '#0f1e25',
overlayImage: './inc/img/3px-tile.webp', /* Optional */
minOverlay: '0.6', /* Optional, Default='0'; */
transitionDuration: 2000
}

const responsiveBg = new ChameleonBackgrounds(options);
</script>

Note: The url property acts as a fallback for older browsers that don't support srcset, or in case no sizes match.
Did you know? This responsive object format is also fully supported in type: 'slider'. Just pass an array of these objects to the src option!

Options
Option Type Default Required Description
element string | HTMLElement 'body' Yes CSS selector or DOM element to attach to.
Examples: "body", "#htmlid", ".htmlclass"
type 'single' | 'slider' 'single' Yes Background mode. Can be "single" or "slider".
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).
Examples: "#656946", "rgb(101, 105, 70)"
overlayImage string | null null No Overlay background (pattern) image URL. Optional but gives great effect combined with a transparent pattern!
minOverlay number 0 No Minimum overlay opacity after fade (0–1). Used to prevent the overlay from completely fading out.
transitionDuration number 2000 Yes Fade duration in milliseconds. The time it takes for the overlay to fade out.
sliderDuration number 8000 Slider only Time each slide is shown (ms). Count starts when the transition duration is past.
sliderLoop boolean false Slider only Restart slider after last slide. Set to true if you want the slider to auto-restart on finish.
fetchPriority string 'auto' No Set this to 'high' to boost network priority for the initial image load (LCP optimization).
lazyLoad boolean true No Defers loading off-screen backgrounds using IntersectionObserver.
transitionMode 'solid' | 'crossfade' 'solid' No Transition effect. 'solid' fades to overlay color, 'crossfade' fades between images.
respectReducedMotion boolean false No Set to true to auto-pause slider if user's OS has animations disabled.
Additional information

Optimize for Largest Contentful Paint (LCP)

To get a great LCP score on PageSpeed, 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!

What's new in v3?

  • True Crossfade Transition — Enable transitionMode: 'crossfade' for a seamless fade between slides!
  • Responsive Images — src now accepts objects with url, srcset, and sizes!
  • Lazy Loading — Uses native IntersectionObserver to defer loading off-screen backgrounds. (Enabled by default!)
  • Play/Pause API — .play() and .pause() added for manual slider control.
  • Accessibility — Auto-pause sliders for users with disabled OS animations via the respectReducedMotion option.

Migration from v1

  1. Remove jQuery — ChameleonBackgrounds v2 uses native DOM APIs and has zero dependencies!
  2. Rename options (optional) — snake_case names still work, but camelCase is now preferred (e.g. transitionDuration instead of transition_duration).
  3. Use new — new ChameleonBackgrounds(options) works identically to v1.
  4. Clean up — Call .destroy() when removing the background (new in v2).

Use transparent patterns as overlayImage

We love to use transparent patterns as overlayImages, these transparent patterns combined with the overlayColor and minOverlay can create amazing effects. Take our site for example, almost every images has different colors but because of the green overlayColor in combination with the minOverlay and overlayImages it looks like every image is part of the design.

Looking for some awesome transparent patterns ?
We love the patterns on transparenttextures.com