'How do I make stacking cards with CSS and JS?
I created the effect I want below:
const container = document.getElementById("container");
const boxes = document.querySelectorAll(".box");
const clearBtn = document.getElementById("clear-button");
const spread = () => {
boxes.forEach((box) => box.classList.remove("selected"));
boxes.forEach((box, i) => {
box.style.left = `${i * 116 + 16}px`;
});
};
const select = (index) => {
spread();
console.log(`selecting ${index}`);
boxes[index].classList.add("selected");
boxes.forEach((box, i) => {
box.style.left = `16px`;
});
};
clearBtn.addEventListener("click", spread, false);
spread();
#container {
display: flex;
}
.box {
position: absolute;
font-size: 64px;
display: flex;
align-items: center;
justify-content: center;
height: 150px;
width: 100px;
top: 5vh;
z-index: 1;
transition: left 1s;
cursor: pointer;
}
.selected {
z-index: 2;
}
.one {
background-color: cyan;
}
.two {
background-color: magenta;
}
.three {
background-color: yellow;
}
button {
position: absolute;
outline: none;
border: none;
background-color: green;
color: white;
padding: 8px;
border-radius: 4px;
top: 185px;
left: 16px;
}
<div id="container">
<div onclick="select(0)" class="box one">1</div>
<div onclick="select(1)" class="box two">2</div>
<div onclick="select(2)" class="box three">3</div>
</div>
<button id="clear-button">Spread</button>
However, the only way I've been able to manage it is with absolute positioning, which I need to avoid so that this component can be manipulated elsewhere on the DOM.
The idea is that I have a collection of "cards." When one is clicked, all of them slide all the way to the left, leaving the selected card on top. Also, it would be ideal to have a way to reverse the process as well.
I wish very badly that I could do this with CSS grid, and it may be possible with Firefox, but that is currently the only browser that supports animating grid-template-columns
.
Ultimately this will need to be done in React, but I am happy to see any answers using any other framework! If there are any libraries that might accomplish this, that would be great too, but again, this will be in React at the end of the day, so that may limit what's available.
This is the only way I've found to accomplish this.
Note: This question is asking a very similar question, but without the movement, and the answer seems to be absolute positioning anyway.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|