I’ve created a hover effect for containers via css animations. It’s not so much about the color change, as the final solution is to switch images instead of divs.
The loop works, but the timings don’t work as expected in some cases.
The delay from last to first element is a bit longer, from first to second element is too short, after the loop has run through once. The more childs the container has, the more confusing the loop gets. In the 4th container, the first one doesn’t show up again.
Any ideas or even better solutions are very welcomed.
body {
display: flex;
gap: 10px;
--collection-timing: 0.5s;
}
body>div {
width: 200px;
height: 200px;
position: relative;
overflow: hidden;
cursor: pointer;
}
div div {
position: absolute;
width: 200px;
height: 200px;
animation-name: slideshow;
animation-play-state: paused;
animation-duration: 0.2s;
animation-iteration-count: infinite;
z-index: -1;
}
div div:nth-child(1) {
animation-delay: var(--collection-timing);
z-index: 2 !important;
}
div div:nth-child(2) {
animation-delay: calc(var(--collection-timing) * 2);
}
div div:nth-child(3) {
animation-delay: calc(var(--collection-timing) * 3);
}
div div:nth-child(4) {
animation-delay: calc(var(--collection-timing) * 4);
}
div div:nth-child(5) {
animation-delay: calc(var(--collection-timing) * 5);
}
div div:nth-child(6) {
animation-delay: calc(var(--collection-timing) * 6);
}
div div:nth-child(7) {
animation-delay: calc(var(--collection-timing) * 7);
}
div div:nth-child(8) {
animation-delay: calc(var(--collection-timing) * 8);
}
div div:nth-child(9) {
animation-delay: calc(var(--collection-timing) * 9);
}
div:has(div:nth-child(1)) div {
animation-duration: var(--collection-timing);
}
div:has(div:nth-child(2)) div {
animation-duration: calc(var(--collection-timing) * 2);
}
div:has(div:nth-child(3)) div {
animation-duration: calc(var(--collection-timing) * 3);
}
div:has(div:nth-child(4)) div {
animation-duration: calc(var(--collection-timing) * 4);
}
div:has(div:nth-child(5)) div {
animation-duration: calc(var(--collection-timing) * 5);
}
div:has(div:nth-child(6)) div {
animation-duration: calc(var(--collection-timing) * 6);
}
div:has(div:nth-child(7)) div {
animation-duration: calc(var(--collection-timing) * 7);
}
div:has(div:nth-child(8)) div {
animation-duration: calc(var(--collection-timing) * 8);
}
div:has(div:nth-child(9)) div {
animation-duration: calc(var(--collection-timing) * 9);
}
div div:nth-child(1) {
background: red;
}
div div:nth-child(2) {
background: green;
}
div div:nth-child(3) {
background: blue;
}
div div:nth-child(4) {
background: yellow;
}
div div:nth-child(5) {
background: greenyellow;
}
div div:nth-child(6) {
background: orange;
}
div div:nth-child(7) {
background: grey;
}
div div:nth-child(8) {
background: plum;
}
body>div:hover div {
animation-play-state: running;
}
body>div:not(:hover) div {
z-index: -1 !important;
}
body>div:not(:hover) div:first-child {
z-index: 2 !important;
}
@keyframes slideshow {
0% {
z-index: 2;
}
100% {
z-index: 1;
}
}
<div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
<div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
<div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
<div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
2
Answers
You can achieve same effect with
@keyframes
as mentioned by @NINE. Just need to add different background images at different percentage.I have created example with two images but you can use more images. Below is working example.
I realise the OP requires a CSS solution, but that can get very unweildy if it’s to cover a lot of cases (in terms of number of images) so I put this JS here in case of use to other readers.
The trick here is to use JS prepend on the last element in the list – takes it off the end and puts it at the beginning (or you could do the reverse using append if you want a different order).
This means there is no need to do any calculation on number of images or on timing related to that. Each image simply stays at the top of the pile (ie is the one shown) for whatever time is required without needing to calculate timings.