I've created a codepen that animates the flexbox inserts and removes.
https://codepen.io/raj_srikar/pen/dyLPRje
This creates 3 boxes with random colors in both of the flexbox containers. On clicking a box, it'll be smoothly removed from its container and will move across the screen and gets inserted at the beginning of the other container by smoothly adjusting the other boxes.
HTML:
<div id="containerA" class="flex-container"></div>
<div id="containerB" class="flex-container"></div>
CSS:
.flex-container {
display: flex;
flex-wrap: wrap;
justify-content: center; /* Center items horizontally */
align-items: center; /* Center items vertically */
padding: 10px;
border: 2px dashed #ccc;
margin-bottom: 20px;
min-height: 150px;
}
.color-box {
width: 100px;
height: 100px;
cursor: pointer;
transition: margin 0.5s ease-in-out; /* Animate margin changes */
flex-shrink: 0; /* Prevent boxes from shrinking */
}
.abs{
position:absolute;
}
JavaScript:
var transDur = 500;
// Function to generate random color
function getRandomColor() {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
// Function to create a color box
function createColorBox(container) {
const box = document.createElement('div');
box.className = 'color-box';
box.style.backgroundColor = getRandomColor();
container.appendChild(box);
box.addEventListener('click', () => {
const sourceContainer = box.parentElement;
const targetContainer = sourceContainer === containerA ? containerB : containerA;
moveBox(box, sourceContainer, targetContainer);
});
}
// Function to move the box to the other container
function moveBox(box, sourceContainer, targetContainer) {
// Create a placeholder to reserve space in the target container
const destDummy = document.createElement('div');
destDummy.className = 'color-box';
destDummy.style.visibility = 'hidden'; // Hide the placeholder
destDummy.style.transition = `width ${transDur}ms ease-in-out`;
// Create a placeholder to unreserve space in the source container
const sourceDummy = destDummy.cloneNode(true);
destDummy.style.width = 0;
targetContainer.insertBefore(destDummy, targetContainer.firstChild);
sourceContainer.insertBefore(sourceDummy, box);
let rect = box.getBoundingClientRect();
box.classList.toggle('abs');
box.style.left = rect.left-rect.width/2+'px';
box.style.top = rect.top+'px';
// Animate the box to the target container
requestAnimationFrame(() => {
sourceDummy.style.width = 0;
destDummy.style.removeProperty('width');
box.style.transition = `transform ${transDur}ms ease-in-out`;
box.style.transform = `translate(${destDummy.offsetLeft - box.offsetLeft - box.offsetWidth/2}px, ${destDummy.offsetTop - box.offsetTop}px)`;
setTimeout(() => {
// Remove the placeholder and move the box to the target container
sourceContainer.removeChild(box);
sourceContainer.removeChild(sourceDummy);
targetContainer.removeChild(destDummy);
targetContainer.insertBefore(box, targetContainer.firstChild);
box.style.removeProperty('transition');
box.style.removeProperty('transform');
box.style.removeProperty('left');
box.style.removeProperty('top');
box.classList.toggle('abs');
}, transDur); // Wait for transition to complete before removing placeholder and moving box
});
}
// Initialize the containers with color boxes
const containerA = document.getElementById('containerA');
const containerB = document.getElementById('containerB');
for (let i = 0; i < 3; i++) {
createColorBox(containerA);
}
for (let i = 0; i < 3; i++) {
createColorBox(containerB);
}
Kind of a lengthy approach but this uses placeholders at the source and destination that changes their widths and the transition affect will make the rest of the flexbox items in the containers to adjust smoothly.
Note: Change the value of transDur
variable to change the transition duration.