Link with target="_blank" still affected by pseudo-class :hover styles after user clicked on it, Chrome only

Viewed 264

After a user clicks to link with target="_blank" link opens the second tab, then the user decides to get back to the previous page (to the first tab) where the user came from with current link.

Till moment user will not drag the cursor to document (page) itself, :hover styling effects still will be there.

Here is simple code example:

.wrapper {
  position: relative;
}

.wrapper:hover .tooltip {
  transition: 'opacity 0.5s step-end';
  opacity: 1;
}

.tooltip {
  position: absolute;
  height: 20px;
  background-color: black;
  opacity: 0;
  color: white;
  padding: 5px 10px;
  border-radius: 5px;
  opacity: 0;
}
<div class="wrapper">
  <a target="_blank" href="https://www.google.com/">Google</a>
  <div class="tooltip">
    Tooltip
  </div>
</div>

And actually code can be even easier, I just described my case above, here is a more basic example:

a:hover {
  background-color: red;
}
<a href="https://www.google.com" target="_blank">Google</a>

That's happening only in Chrome (84.0.4147.125). To make it easier for you to understand the problem, I made screen-recording. Also might happen only in macOS, didn't check on Windows/Linux.

Is it possible somehow to fix it and make it work as other browsers do? After switching tabs, :hover effects are disappearing immediately without waiting till user bring the cursor to page.

2 Answers

A workaround would be to use the :not(:focus) selector on your anchor:

a:hover:not(:focus) {
  background-color: red;
}
<a href="https://www.google.com" target="_blank">Google</a>

Check the jsfiddle to see the working example.

Finally figured out, how to "fix" this. Please check firstly @johannchopin answer before reading this answer, as my fix related to situations when developer trying to control child elements on hover.

So, my solution will be:

const onMouseEnter = () => {
    document.querySelector('a').blur()
}

document.addEventListener("visibilitychange", function() {
  if (document.visibilityState === 'visible') {
    document.addEventListener('mouseenter', () => {
      onMouseEnter()
      document.removeEventListener('mouseenter', onMouseEnter)
    })
  }
});
.wrapper {
  position: relative;
}

.wrapper:hover:not(:focus-within) .tooltip {
  transition: opacity 0.5s step-end;
  opacity: 1;
}

.tooltip {
  position: absolute;
  height: 20px;
  background-color: black;
  opacity: 0;
  color: white;
  padding: 5px 10px;
  border-radius: 5px;
  opacity: 0;
}
<span class="wrapper">
  <a target="_blank" href="https://www.google.com/">Google</a>
  <div class="tooltip">
    Tooltip
  </div>
</span>

Let me explain a bit about what I did here. After I read @johannchopin answer, I found out that :focus works only for the current element. After googling a bit, I found that there's :focus-within pseudo-class to work with current AND with nested elements. Then I added selector like .wrapper:hover:not(:focus-within) .tooltip to hide with opacity my tooltip when user focusing (most of the time it's anyway a click in my case).

But I stacked with another problem, the tooltip wasn't visible on hover after I tried to perform the same after I clicked link once before. So, I added a bit of JavaScript which I think it's pretty clear what it does. Seems there's no pure CSS solutions for issue in general.

Related