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.
- 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!
| 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. |
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 —
srcnow accepts objects withurl,srcset, andsizes! - Lazy Loading — Uses native
IntersectionObserverto 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
respectReducedMotionoption.
Migration from v1
- Remove jQuery — ChameleonBackgrounds v2 uses native DOM APIs and has zero dependencies!
- Rename options (optional) — snake_case names still work, but camelCase is now preferred (e.g.
transitionDurationinstead oftransition_duration). - Use
new—new ChameleonBackgrounds(options)works identically to v1. - 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