Home > Mobile >  Display flex is messing around with my items
Display flex is messing around with my items

Time:12-05

I have a container that has a list of items, each item has an image and some information.

I made a slide function using JavaScript and I got into a little problem, because I'm using translateX, I want the items to be displayed inline.

I made some research and found that I must use display: flex when making a sliding image, and after that, the items are not showing correctly.

If I remove the flex and I put translateY (instead of X) the slide is working (from up/down) but I want from left-right.

Can someone help me?

This is the code that is not work (with display: flex and translateX)

var count = 1;

var next = document.querySelector('button.next');

var items = document.querySelectorAll('div.item');
var size = items[0].clientWidth;

next.addEventListener("click", function(e)
{
    if(count == 2) {
        return;
    }

    count  ;

    document.querySelector('div.main').style.transition = 'transform 1.0s ease-in-out';
    document.querySelector('div.main').style.transform = 'translateX('   ((-size * count))   'px)';
});

var prev = document.querySelector('button.prev');

prev.addEventListener("click", function(e)
{
    if(count == 1) {
        return;
    }

    count--;

    document.querySelector('div.main').style.transition = 'transform 1.0s ease-in-out';
    document.querySelector('div.main').style.transform = 'translateX('   ((-size * count))   'px)';
});
.content {
  margin-left: 50px;
}

.container {
    width: 100%;
    height: 600px;
}

.main {
  display: flex;
  width: 100%;
}

.container-slide {
    width: 100%;
    overflow: hidden;
    position: relative;
}

.image {
    width: 100%;
    min-height: 600px;
    max-height: 600px;
    background-clip: padding-box;
    float: left;
    background-size: cover;
    background-position: center center;
    position: relative;
}

.info {
  position: absolute;
    bottom: 0;
    left: 0;
    width: 70%;
    color: white;
    background: green;
    padding: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.buttons-info {
    margin-left: 30px;
}

button.prev, button.next {
  margin-top: 50px;
}

.show-list-pages {
     position: absolute;
    bottom: 20px;
    right: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: white;
}
<div class="content">
    <div class="container container-slide">
        <div class="main">
            <div class="item">
                <div class="image" style="background-image: url('https://i.redd.it/7nk7p8gl90371.jpg')">
                    <div class="info">
                        <div class="buttons-info">
                            <div class="show-main-text">
                                <span>title item 2</span>
                            </div>
                        </div>
                        <div class="buttons-item">
                            <a href="#">
                                <button><span>button 1</span></button>
                            </a>
                        </div>
                    </div>
                    <div class="show-list-pages">
                        <div class="show-current-page">
                            <span>1</span>
                        </div>
                        <div class="show-count-pages">
                            <span>/ 2</span>
                        </div>
                    </div>
                </div>
            </div>
            <div class="item">
                <div class="image" style="background-image: url('https://assets.hongkiat.com/uploads/minimalist-dekstop-wallpapers/4k/original/14.jpg')">
                    <div class="info">
                        <div class="buttons-info">
                            <div class="show-main-text">
                                <span>title item 1</span>
                            </div>
                        </div>
                        <div class="buttons-item">
                            <a href="#">
                                <button><span>button 1</span></button>
                            </a>
                        </div>
                    </div>
                    <div class="show-list-pages">
                        <div class="show-current-page">
                            <span>1</span>
                        </div>
                        <div class="show-count-pages">
                            <span>/ 2</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<button class="prev">prev</button>
<button class="next">next</button>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

This is the other code without display: flex and translateX (is working) but the next item is not showing (because is not on inline, is under the first item)

var count = 1;

var next = document.querySelector('button.next');

var items = document.querySelectorAll('div.item');
var size = items[0].clientWidth;

next.addEventListener("click", function(e)
{
    if(count == 2) {
        return;
    }

    count  ;

    document.querySelector('div.main').style.transition = 'transform 1.0s ease-in-out';
    document.querySelector('div.main').style.transform = 'translateX('   ((-size * count))   'px)';
});

var prev = document.querySelector('button.prev');

prev.addEventListener("click", function(e)
{
    if(count == 1) {
        return;
    }

    count--;

    document.querySelector('div.main').style.transition = 'transform 1.0s ease-in-out';
    document.querySelector('div.main').style.transform = 'translateX('   ((-size * count))   'px)';
});
.content {
  margin-left: 50px;
}

.container {
    width: 100%;
    height: 600px;
}

.main {
  /*display: flex;*/
  width: 100%;
}

.container-slide {
    width: 100%;
    overflow: hidden;
    position: relative;
}

.image {
    width: 100%;
    min-height: 600px;
    max-height: 600px;
    background-clip: padding-box;
    float: left;
    background-size: cover;
    background-position: center center;
    position: relative;
}

.info {
  position: absolute;
    bottom: 0;
    left: 0;
    width: 70%;
    color: white;
    background: green;
    padding: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.buttons-info {
    margin-left: 30px;
}

button.prev, button.next {
  margin-top: 50px;
}

.show-list-pages {
     position: absolute;
    bottom: 20px;
    right: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: white;
}
<div class="content">
    <div class="container container-slide">
        <div class="main">
            <div class="item">
                <div class="image" style="background-image: url('https://i.redd.it/7nk7p8gl90371.jpg')">
                    <div class="info">
                        <div class="buttons-info">
                            <div class="show-main-text">
                                <span>title item 2</span>
                            </div>
                        </div>
                        <div class="buttons-item">
                            <a href="#">
                                <button><span>button 1</span></button>
                            </a>
                        </div>
                    </div>
                    <div class="show-list-pages">
                        <div class="show-current-page">
                            <span>1</span>
                        </div>
                        <div class="show-count-pages">
                            <span>/ 2</span>
                        </div>
                    </div>
                </div>
            </div>
            <div class="item">
                <div class="image" style="background-image: url('https://assets.hongkiat.com/uploads/minimalist-dekstop-wallpapers/4k/original/14.jpg')">
                    <div class="info">
                        <div class="buttons-info">
                            <div class="show-main-text">
                                <span>title item 1</span>
                            </div>
                        </div>
                        <div class="buttons-item">
                            <a href="#">
                                <button><span>button 1</span></button>
                            </a>
                        </div>
                    </div>
                    <div class="show-list-pages">
                        <div class="show-current-page">
                            <span>1</span>
                        </div>
                        <div class="show-count-pages">
                            <span>/ 2</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<button class="prev">prev</button>
<button class="next">next</button>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

This is the code without display: flex and translateY instead of X, is working from up-down, but I want from left-right

var count = 1;

var next = document.querySelector('button.next');

var items = document.querySelectorAll('div.item');
var size = items[0].clientWidth;

next.addEventListener("click", function(e)
{
    if(count == 2) {
        return;
    }

    count  ;

    document.querySelector('div.main').style.transition = 'transform 1.0s ease-in-out';
    document.querySelector('div.main').style.transform = 'translateY('   ((-size * count))   'px)';
});

var prev = document.querySelector('button.prev');

prev.addEventListener("click", function(e)
{
    if(count == 1) {
        return;
    }

    count--;

    document.querySelector('div.main').style.transition = 'transform 1.0s ease-in-out';
    document.querySelector('div.main').style.transform = 'translateY('   ((-size * count))   'px)';
});
.content {
  margin-left: 50px;
}

.container {
    width: 100%;
    height: 600px;
}

.main {
  /*display: flex;*/
  width: 100%;
}

.container-slide {
    width: 100%;
    overflow: hidden;
    position: relative;
}

.image {
    width: 100%;
    min-height: 600px;
    max-height: 600px;
    background-clip: padding-box;
    float: left;
    background-size: cover;
    background-position: center center;
    position: relative;
}

.info {
  position: absolute;
    bottom: 0;
    left: 0;
    width: 70%;
    color: white;
    background: green;
    padding: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.buttons-info {
    margin-left: 30px;
}

button.prev, button.next {
  margin-top: 50px;
}

.show-list-pages {
     position: absolute;
    bottom: 20px;
    right: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: white;
}
<div class="content">
    <div class="container container-slide">
        <div class="main">
            <div class="item">
                <div class="image" style="background-image: url('https://i.redd.it/7nk7p8gl90371.jpg')">
                    <div class="info">
                        <div class="buttons-info">
                            <div class="show-main-text">
                                <span>title item 2</span>
                            </div>
                        </div>
                        <div class="buttons-item">
                            <a href="#">
                                <button><span>button 1</span></button>
                            </a>
                        </div>
                    </div>
                    <div class="show-list-pages">
                        <div class="show-current-page">
                            <span>1</span>
                        </div>
                        <div class="show-count-pages">
                            <span>/ 2</span>
                        </div>
                    </div>
                </div>
            </div>
            <div class="item">
                <div class="image" style="background-image: url('https://assets.hongkiat.com/uploads/minimalist-dekstop-wallpapers/4k/original/14.jpg')">
                    <div class="info">
                        <div class="buttons-info">
                            <div class="show-main-text">
                                <span>title item 1</span>
                            </div>
                        </div>
                        <div class="buttons-item">
                            <a href="#">
                                <button><span>button 1</span></button>
                            </a>
                        </div>
                    </div>
                    <div class="show-list-pages">
                        <div class="show-current-page">
                            <span>1</span>
                        </div>
                        <div class="show-count-pages">
                            <span>/ 2</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<button class="prev">prev</button>
<button class="next">next</button>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

If you are looking for a carousel. this is what I changed in CSS.

.main {
  display: flex;
  width: 200%;
}
.item{
  width:100%;
}

this is what I changed in JS.

//in next -50% it shifts half way through .main
 document.querySelector('div.main').style.transform = 'translateX(-50%)';
// in prev 0% it goes back to start
 document.querySelector('div.main').style.transform = 'translateX(0%)';

var count = 1;

var next = document.querySelector('button.next');

var items = document.querySelectorAll('div.item');
var size = items[0].clientWidth;

next.addEventListener("click", function(e)
{
    if(count == 2) {
        return;
    }

    count  ;

    document.querySelector('div.main').style.transition = 'transform 1.0s ease-in-out';
    document.querySelector('div.main').style.transform = 'translateX(-50%)';
});

var prev = document.querySelector('button.prev');

prev.addEventListener("click", function(e)
{
    if(count == 1) {
        return;
    }

    count--;

    document.querySelector('div.main').style.transition = 'transform 1.0s ease-in-out';
    document.querySelector('div.main').style.transform ='translateX(-0%)';
});
.content {
  margin-left: 50px;
}

.container {
    width: 100%;
    height: 600px;
}

.main {
  display: flex;
  width: 200%;
}

.container-slide {
    width: 100%;
    overflow: hidden;
    position: relative;
}

.image {
    width: 100%;
    min-height: 600px;
    max-height: 600px;
    background-clip: padding-box;
    float: left;
    background-size: cover;
    background-position: center center;
    position: relative;
}

.info {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    color: white;
    background: green;
    padding: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.item{
  width:100%;
}
.buttons-info {
    margin-left: 30px;
}

button.prev, button.next {
  margin-top: 50px;
}

.show-list-pages {
     position: absolute;
    bottom: 20px;
    right: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: white;
}
<div class="content">
    <div class="container container-slide">
        <div class="main">
            <div class="item">
                <div class="image" style="background-image: url('https://i.redd.it/7nk7p8gl90371.jpg')">
                    <div class="info">
                        <div class="buttons-info">
                            <div class="show-main-text">
                                <span>title item 2</span>
                            </div>
                        </div>
                        <div class="buttons-item">
                            <a href="#">
                                <button><span>button 1</span></button>
                            </a>
                        </div>
                    </div>
                    <div class="show-list-pages">
                        <div class="show-current-page">
                            <span>1</span>
                        </div>
                        <div class="show-count-pages">
                            <span>/ 2</span>
                        </div>
                    </div>
                </div>
            </div>
            <div class="item">
                <div class="image" style="background-image: url('https://assets.hongkiat.com/uploads/minimalist-dekstop-wallpapers/4k/original/14.jpg')">
                    <div class="info">
                        <div class="buttons-info">
                            <div class="show-main-text">
                                <span>title item 1</span>
                            </div>
                        </div>
                        <div class="buttons-item">
                            <a href="#">
                                <button><span>button 1</span></button>
                            </a>
                        </div>
                    </div>
                    <div class="show-list-pages">
                        <div class="show-current-page">
                            <span>2</span>
                        </div>
                        <div class="show-count-pages">
                            <span>/ 2</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<button class="prev">prev</button>
<button class="next">next</button>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

this is not the optimal solution as I tried to keep that original code. this won't work if you add more than 2 images.

CodePudding user response:

If you would like to change the entire code then here is the solution.

source MEDIUM carousel from scratch in vanilla JS

codepen.io carousel

!(function(d){
  var itemClassName = "carousel__photo";
    items = d.getElementsByClassName(itemClassName),
    totalItems = items.length,
    slide = 0,
    moving = true;
  
  
  // Set classes
function setInitialClasses() {
  // Targets the previous, current, and next items
  // This assumes there are at least three items.
  items[totalItems - 1].classList.add("prev");
  items[0].classList.add("active");
  items[1].classList.add("next");
}
// Set event listeners
function setEventListeners() {
  var next = d.getElementsByClassName('carousel__button--next')[0],
      prev = d.getElementsByClassName('carousel__button--prev')[0];
  next.addEventListener('click', moveNext);
  prev.addEventListener('click', movePrev);
}
  
  
  // Next navigation handler
function moveNext() {
  // Check if moving
  if (!moving) {
    // If it's the last slide, reset to 0, else  1
    if (slide === (totalItems - 1)) {
      slide = 0;
    } else {
      slide  ;
    }
    // Move carousel to updated slide
    moveCarouselTo(slide);
  }
}
// Previous navigation handler
function movePrev() {
  // Check if moving
  if (!moving) {
    // If it's the first slide, set as the last slide, else -1
    if (slide === 0) {
      slide = (totalItems - 1);
    } else {
      slide--;
    }
          
    // Move carousel to updated slide
    moveCarouselTo(slide);
  }
}
  
  function disableInteraction() {
  // Set 'moving' to true for the same duration as our transition.
  // (0.5s = 500ms)
  
  moving = true;
  // setTimeout runs its function once after the given time
  setTimeout(function(){
    moving = false
  }, 500);
}
  
  
  function moveCarouselTo(slide) {
  // Check if carousel is moving, if not, allow interaction
  if(!moving) {
    // temporarily disable interactivity
    disableInteraction();
    // Update the "old" adjacent slides with "new" ones
    var newPrevious = slide - 1,
        newNext = slide   1,
        oldPrevious = slide - 2,
        oldNext = slide   2;
    // Test if carousel has more than three items
    if ((totalItems - 1) > 3) {
      // Checks and updates if the new slides are out of bounds
      if (newPrevious <= 0) {
        oldPrevious = (totalItems - 1);
      } else if (newNext >= (totalItems - 1)){
        oldNext = 0;
      }
      // Checks and updates if slide is at the beginning/end
      if (slide === 0) {
        newPrevious = (totalItems - 1);
        oldPrevious = (totalItems - 2);
        oldNext = (slide   1);
      } else if (slide === (totalItems -1)) {
        newPrevious = (slide - 1);
        newNext = 0;
        oldNext = 1;
      }
      // Now we've worked out where we are and where we're going, 
      // by adding/removing classes we'll trigger the transitions.
      // Reset old next/prev elements to default classes
      items[oldPrevious].className = itemClassName;
      items[oldNext].className = itemClassName;
      // Add new classes
      items[newPrevious].className = itemClassName   " prev";
      items[slide].className = itemClassName   " active";
      items[newNext].className = itemClassName   " next";
    }
  }
}
  
  
  function initCarousel() {
  setInitialClasses();
  setEventListeners();
  // Set moving to false so that the carousel becomes interactive
  moving = false;
}
  
  
  initCarousel();
}(document));
.carousel-wrapper {
  overflow: hidden;
  width: 100%;
}
.carousel-wrapper * {
  box-sizing: border-box;
}
.carousel {
  transform-style: preserve-3d;
}
.carousel__photo {
  opacity: 0;
  position: absolute;
  top:0;
  width: 100%;
  height:60vw;
  max-height:90vh;
  margin: auto;
  padding: 1rem 4rem;
  z-index: 100;
  transition: transform .5s, opacity .5s, z-index .5s;
}

.carousel__photo.initial,
.carousel__photo.active {
  opacity: 1;
  position: relative;
  z-index: 900;
}

.carousel__photo.prev,
.carousel__photo.next {
  z-index: 800;
}
.carousel__photo.prev {
  transform: translateX(-100%); /* Move 'prev' item to the left */
}
.carousel__photo.next {
  transform: translateX(100%); /* Move 'next' item to the right */
}

/* buttons */
.carousel__button--prev,
.carousel__button--next {
  position: absolute;
  top:50%;
  width: 3rem;
  height: 3rem;
  background-color: #FFF;
  transform: translateY(-50%);
  border-radius: 50%;
  cursor: pointer; 
  z-index: 1001; /* Sit on top of everything */
  border: 1px solid black;
}
.carousel__button--prev {
  left:0;
}
.carousel__button--next {
  right:0;
}
.carousel__button--prev::after,
.carousel__button--next::after {
  content: " ";
  position: absolute;
  width: 10px;
  height: 10px;
  top: 50%;
  left: 54%;
  border-right: 2px solid black;
  border-bottom: 2px solid black;
  transform: translate(-50%, -50%) rotate(135deg);
}
.carousel__button--next::after {
  left: 47%;
  transform: translate(-50%, -50%) rotate(-45deg);
}
<div class="carousel-wrapper">
  <div class="carousel">
    <img class="carousel__photo initial" src="https://i.imgur.com/sKV54PO.jpeg">
    <img class="carousel__photo" src="https://i.imgur.com/dZH9gh8.jpeg">
    <img class="carousel__photo" src="https://i.imgur.com/TBgEy0n.jpeg">
    <img class="carousel__photo" src="https://i.imgur.com/1PeQdB4.jpeg">
    <img class="carousel__photo" src="https://i.imgur.com/ox8Cp47.jpeg">
      
    <div class="carousel__button--next"></div>
    <div class="carousel__button--prev"></div>
  </div>
</div>
<iframe name="sif5" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

I created a variable translateAmount that starts at 0 and tracks where the carousel is at, and then it translates by the current amount. That way you can always translate it the right amount, your count variable keeps track of the number of pictures.

I also put a width 100% on the .item and width 200% on the .main div. I needed this because with the display: flex it tends to put everything in the screen.

Take a look:

HTML/JS

<html>
  <head>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <div class="content">
      <div class="container container-slide">
          <div class="main">
            
              <div class="item">
                <div class="image" style="background-image: url('https://i.redd.it/7nk7p8gl90371.jpg')">
                  <div class="info">
                      <div class="buttons-info">
                          <div class="show-main-text">
                              <span>title item 2</span>
                          </div>
                      </div>
                      <div class="buttons-item">
                        <a href="#">
                            <button><span>button 1</span></button>
                        </a>
                      </div>
                  </div>
                  <div class="show-list-pages">
                      <div class="show-current-page">
                          <span>1</span>
                      </div>
                      <div class="show-count-pages">
                          <span>/ 2</span>
                      </div>
                  </div>
                </div>
              </div>
              
              <div class="item">
                <div class="image" style="background-image: url('https://i.redd.it/7nk7p8gl90371.jpg')">
                  <div class="info">
                      <div class="buttons-info">
                          <div class="show-main-text">
                              <span>title item 2</span>
                          </div>
                      </div>
                      <div class="buttons-item">
                        <a href="#">
                            <button><span>button 1</span></button>
                        </a>
                      </div>
                  </div>
                  <div class="show-list-pages">
                      <div class="show-current-page">
                          <span>1</span>
                      </div>
                      <div class="show-count-pages">
                          <span>/ 2</span>
                      </div>
                  </div>
                </div>
              </div>
              
              <div class="item">
                  <div class="image" style="background-image: url('https://assets.hongkiat.com/uploads/minimalist-dekstop-wallpapers/4k/original/14.jpg')">
                    <div class="info">
                        <div class="buttons-info">
                            <div class="show-main-text">
                                <span>title item 1</span>
                            </div>
                        </div>
                        <div class="buttons-item">
                            <a href="#">
                                <button><span>button 1</span></button>
                            </a>
                        </div>
                    </div>
                    <div class="show-list-pages">
                        <div class="show-current-page">
                            <span>1</span>
                        </div>
                        <div class="show-count-pages">
                            <span>/ 2</span>
                        </div>
                    </div>
                  </div>
              </div>
          </div>
      </div>
    </div>
    
    <button class="prev">prev</button>
    <button class="next">next</button>
    
    <script>
      var count = 1;

      var next = document.querySelector('button.next');

      var items = document.querySelectorAll('div.item');
      var size = items[0].clientWidth;
      
      let translateAmount = 0;

      next.addEventListener("click", function(e)
        {
          if(count == 3) {
            return;
        }

        count  ;

        translateAmount -= size;
        document.querySelector('div.main').style.transition = 'transform 1.0s ease-in-out';
        document.querySelector('div.main').style.transform = 'translateX('   translateAmount   'px)';
      });

      var prev = document.querySelector('button.prev');

      prev.addEventListener("click", function(e)
      {
        if(count == 1) {
            return;
        }

        count--;

        translateAmount  = size;
        document.querySelector('div.main').style.transition = 'transform 1.0s ease-in-out';
        document.querySelector('div.main').style.transform = 'translateX('   translateAmount   'px)';
      });
    </script>
    
  </body>
</html>

CSS

.content {
  /* margin-left: 50px; */
  border: 0px solid red;
  width: 100vw;
  overflow: hidden;
}

.container {
    width: 100%;
    height: 600px;
}

.main {
  display: flex;
  width: fit-content;
}

.item {
  width: 100vw;
}

.container-slide {
    width: 100%;
    /* height: 50%; */
    /* overflow: hidden; */
    /* position: relative; */
}

.image {
    width: 100%;
    min-height: 600px;
    max-height: 600px;
    background-clip: padding-box;
    /* float: left; */
    background-size: cover;
    background-position: center center;
    position: relative;
}

.info {
  position: absolute;
    bottom: 0;
    left: 0;
    width: 70%;
    color: white;
    background: green;
    padding: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.buttons-info {
    margin-left: 30px;
}

button.prev, button.next {
  margin-top: 50px;
}

.show-list-pages {
     position: absolute;
    bottom: 20px;
    right: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: white;
}
  • Related