skip to Main Content
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>my slider</title>
    <link rel="icon" type="image/x-icon" href="../pages/images/favicon.ico">

    <!-- stylesheet  -->
    <style type="text/css">
        body {
            margin: 0px;
            padding: 0px;
        }
        .card-container {
            width: 100%;
            overflow: hidden;
            border: 2.5px solid #000000;
            margin: 20px auto;
        }

        .card-slider {
            display: flex;
            border: 1.5px solid #ff0000;
        }
        
        .card {
            flex: 0 0 auto;
            width: 100%;
            max-width: 300px;
            height: 200px;
            margin-right: 20px;
            transition: transform 0.5s ease;
            text-align: center;
        }

        .prev, .next {
            cursor: pointer;
            position: absolute;
            top: 50%;
            margin-top: -285px;
        }

        .next {
            right: 0px;
        }

    </style>

</head>
<body>
    <div class="card-container">
        <div class="card-slider">
            <div class="card" style="background-color: #0ffff0;">Card One</div>
            <div class="card" style="background-color: #cab;">Card Two</div>
            <div class="card" style="background-color: #12abc2;">Card Three</div>
            <div class="card" style="background-color: #9000bc;">Card Four</div>
            <div class="card" style="background-color: #500bc1;">Card Five</div>
            <div class="card" style="background-color: #acb111;">Card Six</div>
        </div>
    </div>
    <button class="prev" onclick="previousSlide()">❮</button>
    <button class="next" onclick="nextSlide()">❯</button>

    <script type="text/javascript">
        let currentCard = 0;
        let cards = document.querySelectorAll(".card");
        let totalCards = cards.length;

        
        function showCard() { 
            cards[currentCard].style.transform = `translateX(${-100}%)`; // trying to move this card left
            // after moving above card space created between currentCard and currentCard +1
            
            // this for loop for  remove space between the cards
            for ( let i = currentCard +1; i < totalCards; i++ ) {
                cards[i].style.transform = `translateX(${-100}%)`;
                console.log("Value of i: ",i, " currentCard: ",currentCard);
            } 
            // after come out from for loop slide currentCard end of the all other cards
            cards[currentCard].style.transform = `translateX(${100 * totalCards }%)`;
            
            // increment currentCard
            currentCard++;
        }
        
        function nextSlide () {
            showCard();
        }
    </script>

</body>
</html>

I’m trying to creat a card slider to slide individual cards
my logic:

function show card() {…}
first statement of this function is slide current card by left -100%
after sliding current card space crated between currentCard and currentCard +1
to remove space creating one for loop to slide cards left -100% one by one

after coming out from for loop move current card end of the last card

increment currentCard;
function nextSlide() {…}
show current card

but first statement of showCard(){…} function and for loop run only once.
why?? what’s wrong in my code please answer my question or help me to provide a better solution or explain my code step by step please…

2

Answers


  1. Your code has logical problem. The transform must increase after sliding, you can use your currentCard variable for that.

    Solution

    for ( let i = currentCard +1; i < totalCards; i++ ) {
       cards[i].style.transform = `translateX(${-100 * (currentCard + 1) }%)`; // Check this line
       console.log("Value of i: ",i, " currentCard: ",currentCard);
    } 
    

    And now you should include the gap (the margin size) between cards, I will use calc css method to sum percentage (%) with px, here is the code:

    for ( let i = currentCard +1; i < totalCards; i++ ) {
       cards[i].style.transform = `translateX(calc(${-100 * (currentCard + 1)}% + ${(currentCard+1) * -20}px ))`; // Add -20px for the cards margin
       console.log("Value of i: ",i, " currentCard: ",currentCard);
    } 
    

    It is working perfectly now.


    Edit:

    More Explanation

    When you press the next button, the for loop will shift every card by -100%, when you click it again, the cards will not be shifted anymore, because the translateX is still the same as the first click -100%.

    So the logic here is to increase the translateX by -100% every click, like: -100% > -200% > -300% > ...

    In your showCard function, the currentCard is incremented by 1 for each execution (of course the function is executed when button is clicked).

    Now, we can use this variable to apply our logic:

    cards[i].style.transform = `translateX(${-100 * (currentCard + 1) }%)`;
    

    The currentCard initial value is 0, and -100 * 0 is equal to 0, but we need it to be -100 on the first execution, so we need to add 1 to it. -100 * 1 = -100

    And it will work, now to get rid of the white space caused created by margin-right: 20px for each card, we will apply the same logic but with -20 instead of -100, and combine the two operations using css calc method.

    cards[i].style.transform = `translateX(calc(${-100 * (currentCard + 1)}% + ${(currentCard + 1) * -20}px ))`;
    

    The value of translateX (with calc method) will be (in click sequence):
    -100% - 20px > -200% - 40px > -300% - 60px > ...

    Login or Signup to reply.
  2. Here is the full infinite scroll you were trying to build. Run the snippet to see it in action.->

    The problem with your code is, you are assuming that, by applying translateX(${-100}%) multiple times, the cards will change their position by the sum of the values. That’s wrong. Applying translateX(${-100}%) twice, won’t move the cards by -200. You have to specify the exact values, because you are assigning a new position to the cards by using =. No matter how many times you apply translateX(${-100}%), the cards will always remain at -100. So the solution is to apply different percentage of move to different card. For example to move the cards to left, the first card should be moved by -100%, the second should be moved by -200%, the third should be moved by -300% and so on. Or to move them to the right, apply 100% to the first card, 200% to the second card and like that.

    let currentCard = 0;
    let cards = document.querySelectorAll(".card");
    let totalCards = cards.length;
    
    function showCard() {
    
      for (let i = 0; i < totalCards; i++) {
        cards[i].style.transform = `translateX(${-100 * (currentCard + 1) }%)`;
      }
    
      for (let i = 0; i <= currentCard; i++) {
        cards[i].style.transform = `translateX(${500 -(100*currentCard) }%)`;
      }
    
      (currentCard <= 4) ? currentCard++ : currentCard = 0;
    }
    
    function nextSlide() {
      showCard();
    }
    
    function previousSlide() {
      //
    }
    body {
      margin: 0px;
      padding: 0px;
      box-sizing: border-box;
    }
    
    .card-container {
      position: relative;
      flex-shrink: 1;
      display: flex;
      flex-basis: 1;
      overflow: auto;
      border: 2.5px solid #000000;
      max-width: 1000px;
    }
    
    .card-slider {
      display: flex;
      flex-grow: 1;
      width: 100%;
    }
    
    .card {
      display: flex;
      min-width: 200px;
      flex-basis: 1;
      flex-grow: 1;
      justify-content: center;
      align-items: center;
      max-width: 300px;
      height: 200px;
      transition: transform 0.5s ease;
      text-align: center;
      padding: 10px;
      color: white;
    }
    
    .card img {
      display: flex;
      max-width: 200px;
      justify-content: center;
      align-items: center;
    }
    
    .prev,
    .next {
      padding: 5px;
      cursor: pointer;
      position: absolute;
      top: 50%;
      z-index: 1;
      transform: translateY(-50%);
    }
    
    .next {
      right: 0px;
    }
    <body>
      <div class="card-container">
        <button class="prev" onclick="previousSlide()">&#10094;</button>
        <button class="next" onclick="nextSlide()">&#10095;</button>
        <div class="card-slider">
          <div class="card">
            <img src='https://upload.wikimedia.org/wikipedia/commons/f/f4/BMW_logo_%28gray%29.svg' /> </div>
          <div class="card" style="background-color: #cab;">Card Two</div>
          <div class="card" style="background-color: #12abc2;">Card Three</div>
          <div class="card" style="background-color: #9000bc;">Card Four</div>
          <div class="card">
            <img src='https://upload.wikimedia.org/wikipedia/en/a/a1/Larsen%26Toubro_logo.svg' />
          </div>
          <div class="card" style="background-color: #acb111;">Card Six</div>
        </div>
      </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search