I have div container
with list (cards) inside. When I hover it, cards start to moving (translateX animation
). container
\'s width
Here is the same effect that you mentioned, with a little tweak on your CSS and a helpful hand from jQuery.
Change your selector for the translateX
animation to apply on each of the .card
boxes when their immediate parent is hovered, and not the .cards
(which is the immediate parent of the .card
s). This is because you'd want the cards to move to the left, and not the window through which they appear while making the movement.
That is,
.cards:hover .card {
transform: translateX(-100px);
transition-duration: 1.5s;
animation-duration: 1.5s;
animation-fill-mode: forwards;
}
var $container = $('.container');
var cardWidth = 100;
$container.on('mouseenter', function (e) {
e.preventDefault();
var $card0Clone = $('.card').eq(0).clone(); // clone of the first .card element
$('.cards').append($card0Clone);
updateWidth();
});
$container.on('mouseleave', function (e) {
e.preventDefault();
var $cards = $('.card');
$cards.eq(0).remove(); // remove the last .card element
});
function updateWidth() {
$('.cards').width(($('.card').length) * cardWidth); // no of cards in the queue times the width of each card would result in a container fit enough for all of them
}
Code Explained
As you move in the mouse pointer, a clone of the first card is created, and appended to the end of the cards collection. Further, as you move the mouse out of the hover area, the original .card
(which was cloned earlier) will be removed from the head of the queue - hence, producing a cyclic effect.
The real trick though is with the updateWidth
function. Every time the mouse enters the .container
the width of the .card
s' immediate parent (i.e. .cards
div) is updated, so that .cards
div is wide enough to fit in all the .card
s, and therefore, making sure that each of the cards push against each other and stay in one line at the time the translation animation is being done.