how to manage z-index on carousel elements?

46 views Asked by At

I want to create a infinite carousel, with the top-left picture sliding to the right-end of the list of elements, passing behind the others.

My problem is the transformX, which creates a new stack for z-index, in a way I can't have my element to be really behind all others.

I'm using plain javascript, and you can see the actual result in jsfiddle

    <div id="galerie" style="display: flex;">
      <div class="picture" style="background-color: black; width: 100px;">
        <p>picture 1</p>
      </div>     
      <div class="picture" style="background-color: blue; width: 100px;">
        <p>picture 2</p>
      </div>  
      <div class="picture" style="background-color: orange; width: 100px;">
        <p>picture 3</p>
      </div>
      <div class="picture" style="background-color: green; width: 100px;">
        <p>picture 4</p>
      </div>
    </div>
    document.addEventListener('DOMContentLoaded', function() {
        var slider = document.querySelector('#galerie');
        var items = slider.querySelectorAll('.picture');

        let currentIndex = 0;

        function moveItems() {
            currentIndex = (currentIndex + 1) % items.length;
            let translationVector;
            items.forEach((item, index) => {
                item.style.zIndex = 0;
                if (index === currentIndex -2 || (index === (items.length -2) && currentIndex === 0) || (index === (items.length -1) && currentIndex === 1)) {
                    item.style.zIndex = -100;
                } 
                if (currentIndex == 0) {
                    if (index == items.length - 1){
                        translationVector = items.length * -100
                    } else {
                        translationVector = 0;
                    }
                    
                } else if ( currentIndex == 1) {
                    translationVector = -100;
                } else if (index < currentIndex - 1){
                    translationVector = (items.length - currentIndex) *100;
                } else {
                    translationVector = -currentIndex * 100;
                }

                item.style.transform = `translateX(${translationVector}px)`;
                if (index === currentIndex -2 || (index === (items.length -2) && currentIndex === 0) || (index === (items.length -1) && currentIndex === 1)) {
                    item.style.zIndex = 0;
                }            
            })
        }
        if (items.length > 2){
            setInterval(moveItems, 5000); // Move items every 5 seconds
        }
    });

At the first step of the carousel, picture 0 goes to the left (it will be partially hidden by overflow: hidden on parent), and others pictures also move 1 step left.

At the second step, picture 0 moves to the right, BEHIND the other pictures. Other pictures continue to move one step left.

At the third step, picture 1 moves to the right, BEHIND the other pictures, except it passes IN FRONT OF picture 0. It should move BEHIND ALL other pictures. Other pictures move one step left.

1

There are 1 answers

0
makayabou On

It looks like your problem is with the transform step, which creates a new z-index stack. When you apply a transform on an element, the elements goes to a new stacking context. See https://developer.mozilla.org/docs/Web/CSS/CSS_positioned_layout/Understanding_z-index/Stacking_context