how to add dot in the active nav menu

1.3k Views Asked by At

hello this is my nav menu code i've added animation like a dot move along when i hover over my nav menu. but i don't know how to make that dot to be static in the active menu .

ex: (menu1) this is my menu , when it'active i want that dot beside my menu (menu1.) like this kind of i want if anyone find the solution please give me the code

body {
  font-family: "Sprint Sans Ofc";
}
.navMenu {
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  White-space:nowrap;
  padding-right:20px;
  padding left:30px;
}

.navMenu a {
  color: #000000;
  text-decoration: none;
  font-size: 1.3em;
  text-transform: captilalize;
  font-weight: 600;
  display: inline-block;
  padding:30px;
  -webkit-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
}

.navMenu a:hover {
  color: #000000;
}
.navMenu a:active {
    color:#000000;
}

.navMenu .dot {
  width: 5px;
  height: 5px;
  background: #D61E39;
  border-radius: 50%;
  opacity: 0;
  margin:-44px;
  -webkit-transform: translateX(30px);
  transform: translateX(30px);
  -webkit-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
}
.navMenu a:nth-child(1):hover ~ .dot {
  -webkit-transform: translateX(30px);
  transform: translateX(145px);
  -webkit-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
  opacity: 1;
}

.navMenu a:nth-child(2):hover ~ .dot {
  -webkit-transform: translateX(110px);
  transform: translateX(280px);
  -webkit-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
  opacity: 1;
}

.navMenu a:nth-child(3):hover ~ .dot {
  -webkit-transform: translateX(200px);
  transform: translateX(415px);
  -webkit-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
  opacity: 1;
}

.navMenu a:nth-child(4):hover ~ .dot {
  -webkit-transform: translateX(285px);
  transform: translateX(550px);
  -webkit-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
  opacity: 1;
}
navMenu a:nth-child(1):active ~ .dot {
  position: relative;
  left:40px;
  bottom:10px;
  opacity: 1;
}
.navMenu a:nth-child(1):active ~ .dot {
    left:20px;
    opacity:1;
}
<body>
    <nav class="navMenu">
      <a href="#">menu1</a>
      <a href="#">menu2</a>
      <a href="#">menu3</a>
      <a href="#">menu4</a>
      <div class="dot"></div>
    </nav>
  </body>

1

There are 1 best solutions below

2
gru On

The challenge with your .dot element is to apply the CSS styles (especially the transform values) in a way, that both hover and active states are handled correctly.

In order to achieve this, I'm using CSS selectors like this one:

.navMenu a:nth-child(2):hover~.dot,
.navMenu:not(:hover) a:nth-child(2).active~.dot {

Basically, this means, do the animation if either

  • the element is currently being hovered
  • or the link is active (i.e. it was clicked before), BUT with the limitation that the parent .navMenu is currently not being hovered.

The second rule guarantees, that a hover has the highest priority when setting the destination of the .dot element (especially, this makes the dot move away from the currently active item). Otherwise, the dot wouldn't move and stick to the .active menu item.

Check out my approach below (btw, no need for -webkit properties here):

const anchors = document.querySelectorAll('nav a')

anchors.forEach(anchor => anchor.addEventListener("click", onClick));

function onClick(e) {
  anchors.forEach(achor => achor.classList.remove('active'))
  e.target.classList.add('active')
}
body {
  font-family: "Sprint Sans Ofc";
}

.navMenu {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  White-space: nowrap;
  padding-right: 20px;
  padding left: 30px;
}

.navMenu a {
  color: #000000;
  text-decoration: none;
  font-size: 1.3em;
  text-transform: captilalize;
  font-weight: 600;
  display: inline-block;
  padding: 30px;
  transition: all 0.2s ease-in-out;
}

.navMenu a:hover {
  color: #000000;
}

.navMenu a:active {
  color: #000000;
}

.navMenu .dot {
  width: 5px;
  height: 5px;
  background: #D61E39;
  border-radius: 50%;
  opacity: 1;
  margin: -44px;
  transform: translateX(-30px);
  transition: all 0.2s ease-in-out;
}

.navMenu a:nth-child(1):hover~.dot,
.navMenu:not(:hover) a:nth-child(1).active~.dot {
  transform: translateX(145px);
}

.navMenu a:nth-child(2):hover~.dot,
.navMenu:not(:hover) a:nth-child(2).active~.dot {
  transform: translateX(280px);
}

.navMenu a:nth-child(3):hover~.dot,
.navMenu:not(:hover) a:nth-child(3).active~.dot {
  transform: translateX(415px);
}

.navMenu a:nth-child(4):hover~.dot,
.navMenu:not(:hover) a:nth-child(4).active~.dot {
  transform: translateX(550px);
}
<body>
  <nav class="navMenu">
    <a href="#">menu1</a>
    <a href="#">menu2</a>
    <a href="#">menu3</a>
    <a href="#">menu4</a>
    <div class="dot"></div>
  </nav>
</body>