I am working on a CSS-only carousel with an autoplay feature.
A keyframe animation sets a margin-left to .slide-snapper (div which controls scroll-snap-align and the animations) which causes the slide to move to the left. It works totally fine in Chrome, but in Firefox setting a margin-left (or left alternatively) has no effect on the scroll. If inspected you can see the div element moving but without the expected effect.
Why is this behavior different in Firefox?
*, *:after, *:before {
box-sizing: border-box;
}
/* Example images */
#slide_1 {
background-image: url(https://images.unsplash.com/photo-1579353977828-2a4eab540b9a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8c2FtcGxlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=800&q=60);
}
#slide_2 {
background-image: url(https://images.unsplash.com/photo-1561336313-0bd5e0b27ec8?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8c2FtcGxlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=800&q=60);
}
#slide_3 {
background-image: url(https://images.unsplash.com/photo-1600716051809-e997e11a5d52?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8M3x8c2FtcGxlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=800&q=60);
}
#slide_4 {
background-image: url(https://images.unsplash.com/photo-1524419986249-348e8fa6ad4a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTB8fHNhbXBsZXxlbnwwfHwwfHw%3D&auto=format&fit=crop&w=800&q=60);
}
.li_slide {
background-size: cover;
background-position: center;
}
/* Animations */
@keyframes tonext {
75% {
margin-left: 0;
}
95% {
margin-left: calc(100% + 150px);
}
98% {
margin-left: calc(100% + 150px);
}
99% {
margin-left: 0;
}
}
@keyframes snap {
96% {
scroll-snap-align: start;
}
97% {
scroll-snap-align: none;
}
99% {
scroll-snap-align: none;
}
100% {
scroll-snap-align: start;
}
}
@keyframes tostart {
75% {
margin-left: 0;
}
95% {
margin-left: calc(-300% - 450px);
}
98% {
margin-left: calc(-300% - 450px);
}
99% {
margin-left: 0;
}
}
/* Reset */
ol, li {
list-style: none;
margin: 0;
padding: 0;
}
#pSlider {
width: 300px;
height: 300px;
position: relative;
margin: 0 auto;
/* Left, Right Navigation Arrows */
}
#pSlider #slider-container {
display: flex;
height: 100%;
width: 100%;
overflow-x: scroll;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
}
#pSlider #slider-container .li_slide {
position: relative;
width: 100%;
border-radius: 10px;
background-color: khaki;
flex: none;
margin-right: 150px;
}
#pSlider #slider-container .li_slide:nth-child(even) {
background-color: mediumaquamarine;
}
#pSlider #slider-container .li_slide:last-child {
margin-right: 0;
}
#pSlider #slider-container .li_slide .slide-snapper {
/* Auto play */
scroll-snap-align: start;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
animation: tonext 4s infinite ease, snap 4s infinite ease;
}
@media (prefers-reduced-motion: reduce) {
#pSlider #slider-container .li_slide .slide-snapper {
animation-name: none;
}
}
#pSlider #slider-container .li_slide:last-child .slide-snapper {
animation-name: tostart, snap;
}
#pSlider #slider-container:hover .li_slide .slide-snapper, #pSlider #slider-container:focus-within .li_slide .slide-snapper {
animation-name: none;
}
#pSlider:before, #pSlider:after, #pSlider .prev_slide, #pSlider .next_slide {
display: inline-block;
position: absolute;
top: 0;
width: 30px;
height: 100%;
z-index: 2;
cursor: pointer;
}
#pSlider:before, #pSlider:after {
background-repeat: no-repeat;
background-position: center;
background-size: 70%;
}
#pSlider .next_slide {
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
padding: 20px;
}
#pSlider .prev_slide {
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
padding: 20px;
}
#pSlider:before, #pSlider .prev_slide {
content: "";
left: 0px;
}
#pSlider:after, #pSlider .next_slide {
content: "";
right: 0px;
}
#pSlider:after {
z-index: 1;
/* set underneath .next_slide (z: 2)*/
background-image: url("data:image/svg+xml,%3Csvg width='40' height='60' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3Cpolyline points='10 10 30 30 10 50' stroke='rgba(255,255,255,0.9)' stroke-width='4' stroke-linecap='butt' fill='none' stroke-linejoin='round'%3E<%3C/polyline%3E%3C/svg%3E");
}
#pSlider:before {
background-image: url("data:image/svg+xml,%3Csvg width='40' height='60' xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3Cpolyline points='30 10 10 30 30 50' stroke='rgba(255,255,255,0.9)' stroke-width='4' stroke-linecap='butt' fill='none' stroke-linejoin='round'%3E>%3C/polyline%3E%3C/svg%3E");
}
/* Scrollbar */
#pSlider #slider-container::-webkit-scrollbar {
display: none;
height: 5px;
}
#pSlider #slider-container::-webkit-scrollbar-thumb {
background-color: #000;
border-radius: 50px;
}
#pSlider #slider-container::-webkit-scrollbar-track {
background-color: transparent;
}
/* Input */
#sliderSettings {
text-align: center;
}
#slider-width, #slider-height {
text-align: center;
margin-bottom: 20px;
}
h2 {
text-align: center;
}
<h2>CSS Autoplay Carousel</h2>
<div id="sliderSettings">
<label for="slider-width">Slider width in px:</label>
<input type="text" id="slider-width" name="slider-width" minlength="2" maxlength="4" size="6" placeholder="300">
<label for="slider-height">Slider height in px:</label>
<input type="text" id="slider-height" name="slider-height" minlength="2" maxlength="4" size="6" placeholder="300">
</div>
<div id="pSlider">
<ol id="slider-container" dir="ltr">
<li id="slide_1" class="li_slide">
<div class="slide-snapper"></div>
<a class="prev_slide" href="#slide_4"></a> <a class="next_slide" href="#slide_2"></a> </li>
<li id="slide_2" class="li_slide">
<div class="slide-snapper"></div>
<a class="prev_slide" href="#slide_1"></a> <a class="next_slide" href="#slide_3"></a> </li>
<li id="slide_3" class="li_slide">
<div class="slide-snapper"></div>
<a class="prev_slide" href="#slide_2"></a> <a class="next_slide" href="#slide_4"></a> </li>
<li id="slide_4" class="li_slide">
<div class="slide-snapper"></div>
<a class="prev_slide" href="#slide_3"></a> <a class="next_slide" href="#slide_1"></a> </li>
</ol>
</div>
Simplified version:
@keyframes tonext {
75% {
margin-left: 0;
}
95% {
margin-left: calc(100% + 150px);
}
98% {
margin-left: calc(100% + 150px);
}
99% {
margin-left: 0;
}
}
@keyframes snap {
96% {
scroll-snap-align: start;
}
97% {
scroll-snap-align: none;
}
99% {
scroll-snap-align: none;
}
100% {
scroll-snap-align: start;
}
}
#pSlider {
width: 300px;
height: 300px;
position: relative;
margin: 0 auto;
/* Left, Right Navigation Arrows */
}
#pSlider #slider-container {
display: flex;
height: 100%;
width: 100%;
overflow-x: scroll;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
}
#pSlider #slider-container .li_slide {
position: relative;
width: 100%;
border-radius: 10px;
background-color: khaki;
flex: none;
margin-right: 150px;
}
#pSlider #slider-container .li_slide:nth-child(even) {
background-color: mediumaquamarine;
}
#pSlider #slider-container .li_slide:last-child {
margin-right: 0;
}
#pSlider #slider-container .li_slide .slide-snapper {
/* Auto play */
scroll-snap-align: start;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
animation: tonext 4s infinite ease, snap 4s infinite ease;
}
#pSlider #slider-container .li_slide:last-child .slide-snapper {
animation: none;
}
<div id="pSlider">
<div id="slider-container">
<div id="slide_1" class="li_slide">
<div class="slide-snapper"></div>
</div>
<div id="slide_2" class="li_slide">
<div class="slide-snapper"></div>
</div>
</div>
</div>