1

It is barely noticable but sometimes a small dot appears, like the one below the "prices" menu item:

enter image description here

This is the hover effect I wrote:

:root {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

body {
  margin: 0;
  padding: 0;
}

.navbar {
  display: flex;
  list-style: none;
  padding: 0;
  margin: 0;
}

.navbar > li + li {
  margin-left: 1.5em;
}

.navbar > li > a {
  display: block;
  padding: .5em 0 .05em;
  color: #0e9daf;
  font-size: 2rem;
  text-decoration: none;
  position: relative;
}

.navbar > li > a::after {
  content: "";
  display: block;
  position: absolute;
  left: 50%;
  right: 50%;
  bottom: 0;
  height: 2px;
  background: currentColor;
  transition:
    left .4s ease-out,
    right .4s ease-out;
}

.navbar > li > a.active::after,
.navbar > li > a:hover::after {
  left: 0;
  right: 0;
}
<!DOCTYPE html>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="menu-slide-center.css">
  <title>Menu Slide from Center Effect</title>
</head>
<body>
  <nav>
    <ul class="navbar">
      <li><a href="#" class="active">Home</a></li>
      <li><a href="#">Products</a></li>
      <li><a href="#">Services</a></li>
      <li><a href="#">Prices</a></li>
      <li><a href="#">Contact Us</a></li>
    </ul>
  </nav>
</body>
</html>

I've noticed the same in Chrome and Firefox as well. Any idea how can I fix that?

Johannes
  • 64,305
  • 18
  • 73
  • 130
Zoltan King
  • 1,964
  • 4
  • 18
  • 38
  • 4
    I'm not able to reproduce this in the snippet (in either chrome or safari) but would guess that it's because the `left:50%, right: 50%` rules on `a::after` are running into rounding errors. Maybe cheat and set them both to 51%? – Daniel Beck Apr 09 '21 at 17:25
  • I do see that happening on Products in the snippet on Chrome. If I scroll vertical the dot disappears. – Rob Moll Apr 09 '21 at 17:33
  • Daniel Beck- Yes, thank you, setting both to 51% worked fine. – Zoltan King Apr 09 '21 at 17:34
  • @Daniel Beck I managed to fix it by using `scaleX` instead of percentages and absolute positioning. Changing the percentage value did not work no matter how much I bumped it up. – Zoltan King Apr 09 '21 at 19:00
  • @ZoltanKing Glad you found a better solution! the 51% thing was pretty hacky, I probably shouldn't have suggested it. If you wouldn't mind, please revert the edit to your question that includes the answer -- it tends to be confusing to future readers if answers are mixed in with the question text. Instead you can post that as an answer below, where it can be upvoted etc. Thanks! – Daniel Beck Apr 09 '21 at 19:48

2 Answers2

1

I think the issue was rounding errors due to percentage values as Daniel Beck pointed out in this thread.

I managed to fix it by using a different approach, instead of absolute positioning and percentage values I decided to use scaleX which provides the same visual effect but without the glitch.

.navbar > li > a::after {
  content: "";
  display: block;
  width: 100%;
  height: 2px;
  background: currentColor;
  transition:
    transform .5s ease;
  transform: scaleX(0);
}

.navbar > li > a.active::after,
.navbar > li > a:hover::after {
  transform: scaleX(1);
}
Zoltan King
  • 1,964
  • 4
  • 18
  • 38
  • 1
    Yes, might be related to the explanations found here: https://stackoverflow.com/questions/9983520/webkit-animation-is-leaving-junk-pixels-behind-on-the-screen/17822836 or here: https://stackoverflow.com/questions/17575624/how-can-i-avoid-animation-artifacts-on-my-touch-draggable-border-radius-element/17723401#17723401 the usual solution to issues like this is forcing hardware acceleration like you did with scaleX – CodingKiwi Apr 09 '21 at 21:32
0

It must have to do with rounding issues, as already said. One way to make sure that dot doesn't appear is to add width: 0 and width: 100%; to the two states, and change transition to all:

:root {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

body {
  margin: 0;
  padding: 0;
}

.navbar {
  display: flex;
  list-style: none;
  padding: 0;
  margin: 0;
}

.navbar > li + li {
  margin-left: 1.5em;
}

.navbar > li > a {
  display: block;
  padding: .5em 0 .05em;
  color: #0e9daf;
  font-size: 2rem;
  text-decoration: none;
  position: relative;
}

.navbar > li > a::after {
  content: "";
  display: block;
  position: absolute;
  left: 50%;
  right: 50%;
  width: 0;
  bottom: 0;
  height: 2px;
  background: currentColor;
  transition: all .4s ease-out;
}

.navbar > li > a.active::after,
.navbar > li > a:hover::after {
  left: 0;
  right: 0;
  width: 100%;
}
<!DOCTYPE html>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="menu-slide-center.css">
  <title>Menu Slide from Center Effect</title>
</head>
<body>
  <nav>
    <ul class="navbar">
      <li><a href="#" class="active">Home</a></li>
      <li><a href="#">Products</a></li>
      <li><a href="#">Services</a></li>
      <li><a href="#">Prices</a></li>
      <li><a href="#">Contact Us</a></li>
    </ul>
  </nav>
</body>
</html>
Johannes
  • 64,305
  • 18
  • 73
  • 130