skip to Main Content

I’m encountering an issue with implementing a hover effect on underlined links using SCSS. I’m aiming to create a transition where, on hover, the text color changes to red, and the underline disappears momentarily before being redrawn in red from left to right. When hover finishes first the red underline should dissapear and only then the original, black underline should appear again (without animation). The first step works, however, I’m having trouble ensuring that the transition from the hovered element finishes before the non-hovered element is displayed. I’ve tried experimenting with transition-delay but to no avail. You can see the issue in the following code – notice how black underline appears BEFORE the red line completely shrinks when hover ends (on mouse leave). Can you help?

a {
  position: relative;
  text-decoration: underline;
  color: black;
  transition: color 0.3s;
}

a::before {
  content: '';
  position: absolute;
  width: 0;
  height: 1px;
  bottom: 0;
  left: 0;
  background-color: red;
  transition: width 0.3s;
}

a:hover {
  text-decoration: none;
  color: red;
}

a:hover::before {
  width: 100%;
}
<a href="google.com">My link to Google</a>

3

Answers


  1. For the effect you want to achieve, first set text-decoration:none in the a selector.

    Then, for the underline when not hovering add pseudo after element:

    a {
      position: relative;
      color: black;
      text-decoration: none;
    }
    
    a::before {
      content: '';
      position: absolute;
      width: 0;
      height: 1px;
      bottom: 0;
      z-index:10;
      left: 0;
      background-color: red;
      transition: width 0.3s;
    }
    
    a::after {
       content: '';
      position: absolute;
      width: 100%;
      height: 1px;
      bottom: 0;
      left: 0;
      background-color: black;
      transition: width 0s;
      transition-delay: 0.3s;
    }
    
    a:hover {
      color: red;
    }
    
    a:hover::before {
      width: 100%;
    }
    
    a:hover::after {
      width: 0%;
    }
    <a href="google.com">My link to Google</a>

    I’ve added transition-delay to wait for the red line to disappear. Also, z-index in the before element so that when link is hovered it doesn’t stay hidden under the after element.

    You can delay the transition of after element to happen exactly when you want or you can also start transition from right:0 for giving the loading bar effect.

    Login or Signup to reply.
  2. You can do the wished effect (kinda) using the opacity aka color of the text-decoration.
    when the a tag is hoverd, you can set the following:
    text-decoration: underline transparent;

    with adding the transition:
    text-decoration 0.9s ease;

    in the a tag styling. ( set the wished length instead of 0.9s
    this does have the side effect of the underline can be seen a bit when the red line is shown, im sure you can play around with the idea to find a fix for that issue.
    here is a snippet to test:

    a {
      position: relative;
      color: black;
      text-decoration: underline;
      transition: color 0.3s;
      transition: text-decoration 0.9s ease;
    }
    
    a::before {
      content: '';
      position: absolute;
      width: 0;
      height: 1px;
      bottom: 0;
      left: 0;
      background-color: red;
      transition: width 0.3s;
    }
    
    a:hover {
      text-decoration: underline transparent;
      color: red;
    }
    
    a:hover::before {
      width: 100%;
    }
    <a href="google.com">My link to Google</a>
    Login or Signup to reply.
  3. Set transition-delay to a in normal state

    a {
      position: relative;
      text-decoration: underline;
      color: black;
      transition: color 0.3s, text-decoration-color 0s 0.3s;
    }
    
    a::before {
      content: '';
      position: absolute;
      width: 0;
      height: 1px;
      bottom: 0;
      left: 0;
      background-color: red;
      transition: width 0.3s;
    }
    
    a:hover {
      text-decoration: none;
      text-decoration-color: transparent;
      color: red;
      transition: width 0.3s;
      transition: color 0.3s;
    }
    
    a:hover::before {
      width: 100%;
    }
    <a href="google.com">My link to Google</a>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search