I'm making a simple CSS slider using the clip-path
property to change images. After changing the image, it should be black and white for a couple of seconds, then become colored.
This is my simple example.
body {
margin: 0; display: flex;
justify-content: center; align-items: center;
height: 100vh; background: #eee;
}
.slider_input {
position: absolute; left: -9999px;
}
.block_image {
position: relative;
width: 300px; height: 400px;
overflow: hidden;
}
.image {
position: absolute; top: 0; left: 0;
width: 100%; height: 100%;
object-fit: contain;
pointer-events: none;
opacity: 0;
clip-path: circle(0% at 0% 100%);
filter: grayscale(1);
transition:
clip-path 1.5s ease 0s,
opacity 1.5s ease 0s,
filter 2s ease 2s;
z-index: 1;
}
.slider_input#slide1:checked ~ .block_image .image:nth-child(1),
.slider_input#slide2:checked ~ .block_image .image:nth-child(2)
{
opacity: 1;
clip-path: circle(100% at 50% 50%);
filter: grayscale(0);
z-index: 2;
transition-delay:0s;
}
label {
cursor: pointer;
padding: 0.5em;
background: #333; color: #fff;
margin: 0 5px;
}
<input type="radio" name="group" id="slide1" class="slider_input" checked>
<input type="radio" name="group" id="slide2" class="slider_input">
<label for="slide1">Slide 1</label>
<label for="slide2">Slide 2</label>
<div class="block_image">
<img class="image" src="https://picsum.photos/id/28/300/400" alt="image1">
<img class="image" src="https://picsum.photos/id/21/300/400" alt="image2">
</div>
My problem is that I don't understand the reason why during the transition there is a second clip-path circle despite the fact that I remove the animation playback delay to 0. How can I get rid of the appearance of the second "circle" but at the same time keep the delay so that the black and white image transitions to color with a delay?
Will this work? There is only one circle when the animation happens now.
What I've changed:
removed transitions from inactive .image elements. transition: none;
added transitions only to the active images via radio button CSS
transition:
clip-path 1.5s ease 0s,
opacity 1.5s ease 0s,
filter 2s ease 2s;
adjusted the z-index part. z-index: 1
for base, z-index: 2
for active ones.
Hope this helps!
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: #eee;
}
.slider_input {
position: absolute;
left: -9999px;
}
.block_image {
position: relative;
width: 300px;
height: 400px;
overflow: hidden;
}
.image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: contain;
pointer-events: none;
opacity: 0;
clip-path: circle(0% at 0% 100%);
filter: grayscale(1);
transition: none;
z-index: 1;
}
.slider_input#slide1:checked~.block_image .image:nth-child(1),
.slider_input#slide2:checked~.block_image .image:nth-child(2) {
opacity: 1;
clip-path: circle(100% at 50% 50%);
filter: grayscale(0);
z-index: 2;
transition:
clip-path 1.5s ease 0s,
opacity 1.5s ease 0s,
filter 2s ease 2s;
}
label {
cursor: pointer;
padding: 0.5em;
background: #333;
color: #fff;
margin: 0 5px;
}
<input type="radio" name="group" id="slide1" class="slider_input" checked>
<input type="radio" name="group" id="slide2" class="slider_input">
<label for="slide1">Slide 1</label>
<label for="slide2">Slide 2</label>
<div class="block_image">
<img class="image" src="https://picsum.photos/id/28/300/400" alt="image1">
<img class="image" src="https://picsum.photos/id/21/300/400" alt="image2">
</div>