Solution 1 :

You can use CSS to add and remove the hover. Basic code showing that and added code to toggle active so it can move around.

const menu = document.querySelector(".main-container")
menu.addEventListener("click", function (evt) {
  const item = evt.target.closest(".item")
  if (item) {
    menu.querySelector(".item.active").classList.remove("active")
    item.classList.add("active")
  }
});
.main-container .item.active {
  background-color: green;
}

.item,
.main-container:hover .item.active {
  background-color: yellow;
  transition: background-color .3s;
}

.main-container:hover .item:hover {
  background-color: lime;
  transition: background-color .3s;
}
<div class="main-container">
  <div class="item active">
    <a href="#">item 1</a>
  </div>
  <div class="item">
    <a href="#">item 2</a>
  </div>
  <div class="item">
    <a href="#">item 3</a>
  </div>
</div>

Solution 2 :

You don’t need JS for that.
Just overwrite style when the container is hovered

.main-container:hover .item.hover {
  background-color: transparent;
}
.item.hover {
  background-color: red;
}
.item:hover {
  background-color: red !important;
}
<div class="main-container" >
  <div class="item hover">
    <a href="#">item 1</a>
  </div>
  <div class="item">
    <a href="#">item 2</a>
  </div>
  <div class="item">
    <a href="#">item 3</a>
  </div>
</div>

See jsfiddle: https://jsfiddle.net/hs2yfxm1/

Solution 3 :

If you’re trying to style this based on a hover event you should be utilizing the proper pseudo-class. You mentioned that you always want the first item to be “active”, why not set an .active class that matches the format styling of :hover? For example:

SCSS

.item {
  border-color: red;

  &.active,
  &:hover {
    border-color: blue;
  }
}

CSS

.item {
  border-color: red;
}

.item.active,
.item:hover {
  border-color: blue;
}

Note: In general, it’s best practice to limit your use of JS whenever possible. If something is attainable simply with HTML and CSS, that should be the preferred implementation in most cases.


Other than the stylistic portion, just one comment on your JS. In your example, you’re utilizing e.target this can be dangerous if the element has children in that the target could be the child. Since you’re targeting each element individually (a lot of event listeners that you may want to consider re-working) you can make use of e.currentTarget for other JS needs.

Solution 4 :

Is this what you are after?

.active { background-color:grey; }
.item:hover { background-color:yellow; }
<div class="main-container" >
      <div class="item active">
         <a href="#">item 1</a>
      </div>
      <div class="item">
        <a href="#">item 2</a>
      </div>
      <div class="item">
        <a href="#">item 3</a>
      </div>
    </div>

Problem :

I have a structure like below and I want to toggle active the currently hovered .item element.
I’m using a simple Vanilla JavaScript function that I usually use for click-like situations and it works.

function myFunction(e) {
  var elems = document.querySelectorAll(".hover");
  [].forEach.call(elems, function(el) {
    el.classList.remove("hover");
  });
  e.target.classList.add("hover");
}
<div class="main-container">
  <div class="item hover" onmouseover="myFunction(event)">
    <a href="#">item 1</a>
  </div>
  <div class="item" onmouseover="myFunction(event)">
    <a href="#">item 2</a>
  </div>
  <div class="item" onmouseover="myFunction(event)">
    <a href="#">item 3</a>
  </div>
</div>

So far so good, but here comes the tricky part. When the mouse goes to a sibling element the hover correctly is changing to the inner one.

I tried some CSS ticks but I can’t manage to make it work, any thoughts would be much appreciated

P.S. I prefer Vanilla JavaScript than jQuery

Comments

Comment posted by Sukima

What is special with the

Comment posted by kaize

That’s because I want to always have the first element active even if it’s not hovered and when the mouse leave the section make it active again

Comment posted by Sugar

why don’t you use

Comment posted by Sergey

Or simply add a new class “active” and make 1st child always active

Comment posted by kaize

That’s perfect! If i change the

Comment posted by kaize

That is correct I can’t believe i missed it! I also have a lot of inner element’s depending on the hover but think I will manage to make it work that way, Thanks

Comment posted by Sugar

Does it allow to stack css selectors like that? Or you just post SCSS or something other like that?

Comment posted by HollyOS

Not yet, I believe. That was just SCSS. Updated to have both versions.

Comment posted by kaize

You totally have a point there, I think something like that. I have a lot of inner elements depending on the hover so I will try with an active class an overrides for the hover. Thanks

Comment posted by kaize

That’s close but I want to remove the

By