Image Fragmentation Effect with HTML, CSS, and JavaScript
This article explains how to create a picture‑fragment animation by dividing an image into a grid of small blocks, using CSS background‑size and background‑position together with JavaScript to generate the blocks, apply delays, rotations, scaling, and performance‑optimising techniques.
The author introduces a visual effect that breaks an image into many small pieces, originally used in carousel banners, and shows how to recreate it with modern HTML, CSS, and JavaScript.
Principle
The effect works by creating a container of a given size, generating a fixed number of small boxes, and assigning each box the same background image. By adjusting background-size and background-position , each box displays a different portion of the original picture, effectively re‑assembling the whole image when placed together.
Implementation
HTML structure:
<!DOCTYPE html>
<html>
<head>
<style>
body { width:100%; height:100vh; margin:0; display:flex; justify-content:center; align-items:center; }
.box { width:var(--width); height:var(--height); display:flex; flex-wrap:wrap; justify-content:center; }
.small-box { background-image:url('YOUR_IMAGE_URL'); background-repeat:no-repeat; box-sizing:border-box; }
</style>
</head>
<body>
<div id="box" class="box"></div>
</body>
</html>JavaScript creates the grid and sets each block’s size, position, and animation delay:
document.addEventListener('DOMContentLoaded', () => {
const box = document.getElementById('box');
const { width, height } = box.getBoundingClientRect();
const row = 14; const col = 10;
const smallBoxWidth = width / col;
const smallBoxHeight = height / row;
function createSmallBox() {
for (let i = 0; i < row; i++) {
for (let j = 0; j < col; j++) {
const smallBox = document.createElement('div');
smallBox.classList.add('small-box');
smallBox.style.width = smallBoxWidth + 'px';
smallBox.style.height = smallBoxHeight + 'px';
const offsetX = j * smallBoxWidth * -1;
const offsetY = i * smallBoxHeight * -1;
smallBox.style.backgroundPosition = `${offsetX}px ${offsetY}px`;
smallBox.style.backgroundSize = `${width}px ${height}px`;
const delay = i * 100; // or use other patterns
smallBox.style.animationDelay = `${delay}ms`;
box.appendChild(smallBox);
}
}
}
createSmallBox();
});CSS animation adds opacity fading and optional rotation/scale:
.small-box {
opacity:0;
animation: smallBoxAnimate 2000ms linear forwards;
}
@keyframes smallBoxAnimate {
0% { opacity:0; transform:scale(0.8); }
40% { opacity:0; transform:scale(0.8); }
70% { opacity:1; transform:scale(0.8); }
100% { opacity:1; transform:scale(1); }
}Advanced variations use CSS custom properties to set opposite rotations for neighboring blocks, random delays, or directional wave patterns, e.g.:
const contrary = (i + j) % 2 === 0;
smallBox.style.setProperty('--rotateX', `rotateX(${contrary ? -180 : 0}deg)`);
smallBox.style.setProperty('--rotateY', `rotateY(${contrary ? 0 : -180}deg)`);Performance tips include caching images, pre‑loading with JavaScript Image objects, converting images to base64, or embedding them locally, and ensuring the animation starts only after the image fully loads.
Finally, the article lists several delay patterns (random, diagonal, center‑out, edges‑in) and encourages readers to experiment with their own designs.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.