why li element move on hover of button?

Viewed 84

I am trying to make a simple demo li elements Which is horizontal center followed by Play or Pause button (see attached image ).I am able to make this using Flexbox properties. but facing few issue

Issue:

  1. My li elements are moving or changing it position when I hover the Button.

conditions

  1. we can't give hardcoded width to TEXT or hover text or PLAY or PAUSE .Text can be as big as possible ?

here is my code https://jsbin.com/kobezulipe/edit?html,css,output

li {
  list-style:none;
}

.abc{
    display: flex;
    align-items: center;
    margin: 0 auto;
    width: 100%;
    justify-content: center;
}
.list{
    overflow: hidden;
    left: 0;
    list-style: none;
    display: -ms-flexbox;
    display: flex;
    flex-flow: row nowrap;
    justify-content: center;
    align-items: center;
    text-align: center;
    padding: 0;
    margin: 0;
}

.list li{
   width: 52px;
  margin: 0 9px;
   
}
.list li button{
   border: 1px solid #3A3631;
    width: 52px;
}


.p{
  position: relative;
    height: 100%;
    display: flex;
    align-self: center;
    align-items: center;
    width: initial;
    left: 18px;
    margin-bottom: 0;
}





.container {
  padding: 8px;
  border: 1px solid;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s linear;
}

.text {
  display: none;
}

.button {
  border: 0;
  background: transparent;
  box-sizing: border-box;
  width: 0;
  height: 20px;
  border-color: transparent transparent transparent #202020;
  transition: 100ms all ease;
  cursor: pointer;
  border-style: solid;
  border-width: 10px 0 10px 20px;
  padding: 0
}

.button.paused {
  border-style: double;
  border-width: 0px 0 0px 20px;
}

.button:hover {
  border-color: transparent transparent transparent #404040;
}

.container:hover span {
  display: inline;
}
<div class="abc">
  <ul class='list'>
    <li><button><span></span></button></li>
    <li><button><span></span></button></li>
    <li><button><span></span></button></li>
    <li><button><span></span></button></li>
  </ul>
  <div class="p">
    <div class="container">
    <button class='button'>
    </button>
    <span class="text">Play</span>
  </div>
  </div>
</div>

Attached expected output

Answer pic enter image description here

3 Answers

new answer: ↓

i rewrote the html. and the .p is positioned relative to the .list.

var btn = document.querySelector(".button");

btn.addEventListener("click", function () {
  btn.classList.toggle("paused");
  document.querySelector(".button");
});
li {
  list-style: none;
}

.abc {
  display: flex;
  align-items: center;
  margin: 0 auto;
  width: 100%;
  justify-content: center;
}
.list {
  /* overflow: hidden; */
  left: 0;
  list-style: none;
  display: -ms-flexbox;
  display: flex;
  flex-flow: row nowrap;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 0;
  margin: 0;
  position: relative;
}

.list li {
  width: 52px;
  margin: 0 9px;
}
.list li button {
  border: 1px solid #3a3631;
  width: 52px;
}

.p {
  position: relative;
  height: 100%;
  display: flex;
  align-self: center;
  align-items: center;
  width: initial;
  /* left: 18px; */
  margin-bottom: 0;

  position: absolute;
  right: -18px;
  transform: translateX(100%);
}

.container {
  padding: 8px;
  border: 1px solid;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s linear;
}

.text {
  display: none;
}

.button {
  border: 0;
  background: transparent;
  box-sizing: border-box;
  width: 0;
  height: 20px;
  border-color: transparent transparent transparent #202020;
  transition: 100ms all ease;
  cursor: pointer;
  border-style: solid;
  border-width: 10px 0 10px 20px;
  padding: 0;
}

.button.paused {
  border-style: double;
  border-width: 0px 0 0px 20px;
}

.button:hover {
  border-color: transparent transparent transparent #404040;
}

.container:hover span {
  display: inline;
}
<div class="abc">
  <ul class="list">
    <li>
      <button><span></span></button>
    </li>
    <li>
      <button><span></span></button>
    </li>
    <li>
      <button><span></span></button>
    </li>
    <li>
      <button><span></span></button>
    </li>
    <div class="p">
      <div class="container">
        <button class="button"></button>
        <span class="text">Play longer longer longer</span>
      </div>
    </div>
  </ul>
</div>

hope it can help you。

you can change the .p {width: initial;} to .p {width: 52px;}

It's moving because the flexbox in .abc justify-content: center. When the width of the button changes, everything moves to stay centered.

If you change that to start it will not move.

Alternatively, if you don't want the content to move and you want to keep it centered, and you can't use a hard-coded width, you can try using an overlay. It won't move when you hover, though it might cover up anything next to it:

  1. add a second button next to the first one. remove the text from the original.
  2. set this button to position: absolute so it's positioned above the layout. the parent is already position: relative
  3. only display the overlay during .p:hover. Hide the original button with visibility: hidden so it keeps its width and height.

Example:

li {
  list-style:none;
}

.abc{
    display: flex;
    align-items: center;
    margin: 0 auto;
    width: 100%;
    justify-content: center;
}
.list{
    overflow: hidden;
    left: 0;
    list-style: none;
    display: -ms-flexbox;
    display: flex;
    flex-flow: row nowrap;
    justify-content: center;
    align-items: center;
    text-align: center;
    padding: 0;
    margin: 0;
}

.list li{
   width: 52px;
  margin: 0 9px;
   
}
.list li button{
   border: 1px solid #3A3631;
    width: 52px;
}

.p{
  position: relative;
    height: 100%;
    display: flex;
    align-self: center;
    align-items: center;
    width: initial;
    left: 18px;
    margin-bottom: 0;
}

.container {
  display: inline-flex;
}

.container, .overlay {
  padding: 8px;
  border: 1px solid;
  align-items: center;
  justify-content: center;
}

.overlay {
  position: absolute;
  left: 0;
  top: 0;
  flex-direction: row;
  display: none;
  transition: all 0.2s linear;
}

.p:hover .overlay {
  display: inline-flex;
}

.p:hover .container {
  visibility: hidden;
}

.text {
  white-space: nowrap;
}

.button {
  border: 0;
  background: transparent;
  box-sizing: border-box;
  width: 0;
  height: 20px;
  border-color: transparent transparent transparent #202020;
  transition: 100ms all ease;
  cursor: pointer;
  border-style: solid;
  border-width: 10px 0 10px 20px;
  padding: 0
    overflow: visible;
}

.button.paused {
  border-style: double;
  border-width: 0px 0 0px 20px;
}

.button:hover {
  border-color: transparent transparent transparent #404040;
}

.container:hover span {
  display: inline;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<div class="abc">
  <ul class='list'>
    <li><button><span></span></button></li>
    <li><button><span></span></button></li>
    <li><button><span></span></button></li>
    <li><button><span></span></button></li>
  </ul>
  <div class="p">
    <div class="container">
      <button class='button'>
      </button>
    </div>
    <div class="overlay">
      <button class='button'>
      </button>
      <span class="text">Play, this can be very long</span>
    </div>
  </div>
</div>
</body>

With @kid-jokers answer you can add white-space: nowrap; to container div to allow words to span on one line.

 var btn = document.querySelector(".button");

btn.addEventListener('click',function(){
  btn.classList.toggle('paused');
  document.querySelector(".button");
})
li {
  list-style:none;
}

.abc{
    display: flex;
    align-items: center;
    margin: 0 auto;
    width: 100%;
    justify-content: center;
}
.list{
    overflow: hidden;
    left: 0;
    list-style: none;
    display: -ms-flexbox;
    display: flex;
    flex-flow: row nowrap;
    justify-content: center;
    align-items: center;
    text-align: center;
    padding: 0;
    margin: 0;
}

.list li{
   width: 52px;
  margin: 0 9px;
   
}
.list li button{
   border: 1px solid #3A3631;
    width: 52px;
}


.p{
  position: relative;
    height: 100%;
    display: flex;
    align-self: center;
    align-items: center;
    width: 52px;
    left: 18px;
    margin-bottom: 0;
}





.container {
  padding: 8px;
  border: 1px solid;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s linear;
}

.text {
  display: none;
}

.button {
  border: 0;
  background: transparent;
  box-sizing: border-box;
  width: 0;
  height: 20px;
  border-color: transparent transparent transparent #202020;
  transition: 100ms all ease;
  cursor: pointer;
  border-style: solid;
  border-width: 10px 0 10px 20px;
  padding: 0
}

.button.paused {
  border-style: double;
  border-width: 0px 0 0px 20px;
}

.button:hover {
  border-color: transparent transparent transparent #404040;
}

.container:hover span {
  display: block;
  white-space: nowrap;
}
<div class="abc">
  <ul class='list'>
    <li><button><span></span></button></li>
    <li><button><span></span></button></li>
    <li><button><span></span></button></li>
    <li><button><span></span></button></li>
  </ul>
  <div class="p">
    <div class="container">
    <button class='button'>
    </button>
    <span class="text">Play WHAM! - Jitterbug</span>
  </div>
  </div>
</div>

Related