How can I stop my center div from changing position after I SlideUp another divs?

Viewed 70

I'm creating simple page with a <header> and a <section>. In the section I have 3 divs and I am positioning them with display: flex; and justify-content: space-between.

The problem is that I also use JS slideToggle() on two of them (extreme ones). It is changing the layout of my center div after they are going up. How can I do it so that my center div doesn't change position after one of the others is slid up?

$(document).ready(function() {
  $('#playlist').click(function() {
    $('#nav').slideToggle();
  });
});

$(document).ready(function() {
  $('#songs').click(function() {
    $('#listSongs').slideToggle();

  });
});
section {
  display: flex;
  justify-content: space-between;
}

#listSongs {
  margin-top: 50px;
  height: 550px;
  background-color: black;
  border-radius: 5px;
  font-size: 25px;
  width: 200px;
}

#listSongs p {
  margin-top: 5px;
  width: 200px;
  text-align: center;
  overflow: hidden;
  height: 35px;
  line-height: 50px;
  color: white;
}

#player {
  color: red;
}

#nav {
  margin-top: 50px;
  height: 550px;
  background-color: black;
  border-radius: 20px;
  width: 200px;
}

.hidden {
  margin-top: 50px;
  height: 550px;
  background-color: black;
  border-radius: 20px;
  width: 200px;
  visibility: hidden;
}

#nav p {
  text-align: center;
}

#nav ul {
  list-style-type: none;
  text-align: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
  <div id="listSongs">
    <p>Authors:</p>
    <div class="after"></div>
  </div>
  <div id="player">
    <p>something</p>
  </div>
  <div id="nav">
    <p>something</p>
  </div>
</section>

1 Answers

The issue is because when the slideUp/slideDown/slideToggle methods complete, they set display: none on the target element. This is what causes the layout of your page to shift.

To workaround, and improve the animation, you can use CSS instead. Use the transition property to animate the height setting. Then you can toggle a class which sets height: 0 on the target element. Try this:

$(document).ready(function() {
  $('#playlist').click(function() {
    $('#nav').toggleClass('hide');
  });

  $('#songs').click(function() {
    $('#listSongs').toggleClass('hide');
  });
});
body { background-color: #CCC; }
section {
  display: flex;
  justify-content: space-between;
}

section > div.panel {
  margin-top: 50px;
  height: 550px;
  background-color: black;
  border-radius: 5px;
  font-size: 25px;
  width: 200px;
  transition: height 0.4s;
  overflow: hidden;
}

section > div.panel.hide {
  height: 0;
}

section > div.panel p {
  margin-top: 5px;
  width: 200px;
  text-align: center;
  overflow: hidden;
  height: 35px;
  line-height: 50px;
  color: white;
}

#player {
  color: red;
}

#nav {
  border-radius: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="playlist">Playlist</button>
<button id="songs">Songs</button>
<section>
  <div id="listSongs" class="panel">
    <p>Authors:</p>
    <p>lorem ipsum</p>
    <div class="after"></div>
  </div>
  <div id="player">
    <p>something</p>
  </div>
  <div id="nav" class="panel">
    <p>something</p>
  </div>
</section>

Note that I also rearranged some of the CSS to make it more generic with less repetition.

Related