So, part of the problem is that display: none
does not transition and will immediately hide your element. You’ll want to set that to a timeout to occur after the transition properties have finished.
I’ve thrown together a quick and dirty CodePen that does a basic implementation of the “shuffle”.
Notes:
This is by no means perfect and would require some finesse to get it all working properly.
Depending on your implementation it may be better to
.filter()
your data and then apply the transition effect. This is more of an implementation of the effect than strictly the sorting.
https://codepen.io/hollyos/pen/gOaYQrz?editors=0110
In this example I’m making use of flexbox for the general layout and then utilizing transition
with transform
and width
to re-create the minimize to center effect. It’s important to remember to set the transform-origin
to match the desired location of the “close effect”
CSS
.sorted-list {
display: flex;
flex-wrap: wrap;
list-style: none;
margin: 0;
padding: 0;
> li {
background: #CCC;
box-shadow: 0 2px 8px 1px rgba(33, 33, 33, 0.4);
height: 150px;
width: 25%;
transform-origin: center center;
transition: transform 0.45s ease, width 0.45s ease;
&.hidden {
transform: scale(0);
width: 0;
}
&.d-none {
display: none;
}
}
}
JS
const resetItem = (element) => {
element.classList.remove('d-none');
// Slight delay to allow for the element to be "added" back in
setTimeout((scopedElement) => {
scopedElement.classList.remove('hidden');
}, 1, element);
};
const hideItem = (element) => {
element.classList.add('hidden');
// Delay display: none, since it doesn't transition.
setTimeout((scopedElement) => {
scopedElement.classList.add('d-none');
}, 300, element);
}
(function() {
const nav = document.querySelector('nav');
nav.addEventListener('click', (event) => {
const { group } = event.target.dataset;
// A catch-all for anything that's not group related to reset the list sort.
if (!group) {
document.querySelectorAll('.sorted-list > li').forEach(resetItem);
return;
}
// Ensure "visible" elements are visible
document.querySelectorAll(`.sorted-list > .group-${group}`).forEach(resetItem);
// Hide all other elements
document.querySelectorAll(`.sorted-list > li:not(.group-${group})`).forEach(hideItem);
});
})();