Husna
Husna

Reputation: 1386

Vertical Menu after element move to next li on hover and active with smooth transition

I'm working on a vertical nav menu here I want to add on hover active border move to next li with smooth animation.

nav {
  padding: 50px;
  text-align: center;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  font-size: 0px;
}

ul li {
  position: relative;
  display: inline-block;
  padding: 8px 0;
  width: 80px;
  text-align: center;
  font-size: 15px;
  cursor: pointer;
}

li:after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  height: 34px;
  width: 2px;
  background: red;
  transition: .5s linear;
}

li.active:after {
  left: -1px;
  width: 4px;
  background: green;
  transition: .5s linear;
}

li:nth-child(1):hover~li.active:after {
  top: 0px;
}

li:nth-child(2):hover~li.active:after {
  top: 80px;
}

li:nth-child(3):hover~li.active:after {
  top: 160px;
}

li:nth-child(4):hover~li.active:after {
  top: 240px;
}
<nav>
  <ul>
    <li>one</li>
    <li class="active">two</li>
    <li>three</li>
    <li>four</li>
  </ul>
</nav>

Upvotes: 1

Views: 450

Answers (3)

Malika
Malika

Reputation: 7

<nav>
  <ul>
    <li>one</li>
    <li class="active">two</li>
    <li>three</li>
    <li>four</li>
  </ul>
</nav>

$("nav ul li").hover(function(){
  $("li").removeClass("active");
  $(this).next().addClass('active')
});

Upvotes: 0

Amaresh S M
Amaresh S M

Reputation: 3010

I hope this is what you are expecting.

let addClass = (e) => {
  if (e.target.tagName === 'LI') {
    e.target.classList.add('active');
  }
}

let removeClass = (e) => {
  if (e.target.tagName === 'LI') {
    e.target.classList.remove('active');
  }
}


let list = document.querySelector('.list-elements');
list.addEventListener('mouseover', addClass);
list.addEventListener('mouseout', removeClass);
nav {
  padding: 50px;
  text-align: center;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  font-size: 0px;
}

ul li {
  position: relative;
  display: inline-block;
  padding: 8px 0;
  width: 80px;
  text-align: center;
  font-size: 15px;
  cursor: pointer;
}

li:after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  height: 34px;
  width: 2px;
  background: red;
  transition: .5s linear;
}

li.active::after {
  left: -1px;
  width: 4px;
  background: green;
  transition: .5s linear;
}
<nav>
  <ul class="list-elements">
    <li class="active">one</li>
    <li>two</li>
    <li>three</li>
    <li>four</li>
  </ul>
</nav>

To make a smooth transition you have to add another child element div.

let addClass = (e) => {
  if (e.target.tagName === 'LI') {
    let top = e.target.classList[0];
    let div = document.querySelector('.list-elements div');
    div.style.top = `${parseInt(top)*35}px`;
  }
}
let list = document.querySelector('.list-elements');
list.addEventListener('mouseover', addClass);
nav {
  padding: 50px;
  text-align: center;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  font-size: 0px;
}

ul li {
  position: relative;
  display: inline-block;
  padding: 8px 0;
  width: 80px;
  text-align: center;
  font-size: 15px;
  cursor: pointer;
}

ul:after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 2px;
  background: red;
  transition: .5s linear;
}

li.active::after {
  left: -1px;
  width: 4px;
  background: green;
}

ul div {
  position: absolute;
  top: 0px;
  width: 4px;
  left: -1px;
  background-color: green;
  height: 35px;
  z-index: 9;
  border-radius: 2px;
  transition: .5s linear;
}
<nav>
  <ul class="list-elements">
    <li class="0">one</li>
    <li class="1">two</li>
    <li class="2">three</li>
    <li class="3">four</li>
    <div></div>
  </ul>
</nav>

Upvotes: 2

Temani Afif
Temani Afif

Reputation: 274374

Consider an empty li at the end that will hold the pseudo element and you can easily target that element on hover of any of the other ones:

nav {
  padding: 50px;
  text-align: center;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  font-size: 0px;
}

ul li {
  display: inline-block;
  padding: 8px 0;
  height:35px;
  box-sizing:border-box;
  width: 80px;
  text-align: center;
  font-size: 15px;
  cursor: pointer;
  border-left:2px solid red;
}
ul li:last-child {
  padding:0;
  width:0;
  height:0;
}

ul li:last-child:after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  height: 35px;
  left: -1px;
  width: 4px;
  background: green;
  transition: .5s linear;
}

ul li:nth-child(1):hover ~ li:last-child:after,
li:nth-child(1).active ~ li:last-child:after{
  top: 0px;
}

ul li:nth-child(2):hover ~ li:last-child:after,
li:nth-child(2).active ~ li:last-child:after{
  top: 35px;
}

ul li:nth-child(3):hover ~ li:last-child:after,
li:nth-child(3).active ~ li:last-child:after{
  top: 70px;
}

ul li:nth-child(4):hover ~ li:last-child:after,
li:nth-child(4).active ~ li:last-child:after{
  top: 105px;
}
<nav>
  <ul>
    <li>one</li>
    <li class="active">two</li>
    <li>three</li>
    <li>four</li>
    <li></li>
  </ul>
</nav>

Upvotes: 0

Related Questions