Home > Net >  why li element move on hover of button?
why li element move on hover of button?

Time:12-02

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 enter image description here

CodePudding user response:

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>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

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>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

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>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

hope it can help you。

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

  • Related