Search code examples
csscss-transitionsslidingunderline

Transition sliding underline jumping


I'm trying to use a CSS transition to have a sliding underline on one of my pages (on hover, underline slides in from left to right). I'm using it on multiple li elements at once:

#menu li{
    border-bottom:2px solid transparent;
    width:0px;
    transition:0.8s ease;
    white-space:nowrap;
}
#menu li:hover{
    border-bottom:2px solid #FFE5C7;
    width:100%;
}

Which works, the underline fades in and slides across to underline the list item. The problem is that the list item texts are of different lengths, and for some reason after hovering on a longer string of text, and then moving to a shorter li, the transition will grow the underline to the length of the previous item and then snap back. If that makes sense... example:

Home
Contact Me

If I first hover over "Contact Me", the underline works. If I then move to "Home" the underline grows to the length of the "Contact Me" underline and then snaps back. Not sure why, haven't found a solution that works. I don't want to set the width to a specific number of pixels, I only want the text itself underlined.


Solution

  • According to your code, all the list elements are going to have the same width of 100%, which is ok, but then make sure you apply the animation to the link inside the list element and not the list element itself. Try this instead:

    #menu ul li > a{
        position: relative;
        -o-transition:0.8s ease;
        -ms-transition:0.8s ease;
        -moz-transition:0.8s ease;
        -webkit-transition:0.8s ease;
        transition:0.8s ease;
        white-space:nowrap;
    }
    
    #menu ul li > a:before {
        content: "";
        position: absolute;
        width: 0%;
        height: 2px;
        bottom: 0;
        left: 0;
        background-color: #FFE5C7;
        visibility: hidden;
        -webkit-transition: all 0.3s ease-in-out 0s;
        transition: all 0.3s ease-in-out 0s;
    }
    
    #menu ul li > a:hover:before {
        visibility: visible;
        width: 100%;
    }
    

    Your HTML should look like this:

    <nav id="menu">
        <ul>
            <li>
                <a href="#">Home</a>
            </li>
            <li>
                <a href="#">Contact Me</a>
            </li>
        </ul>
    </nav>