Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap 4 nav-link hover effect

I'm trying to put a hover effect targeting the a-links in the navigation bar only (not the forwardslashes). But I can't seem to access only the a-links, the effect ends up running along the whole navbar instead. Seems to be a conflict with Bootstrap 4 here.

HTML

 <nav class="navbar sticky-top navbar-expand-md navbar-light bg-light">
            <!-- <div class="mx-auto d-sm-flex d-block flex-sm-nowrap"> -->
            <a class="navbar-brand" href="https://www.facebook.com/GetMove.Official/">GET MOVE</a>
            <button
                class="navbar-toggler mr-left custom-toggler"
                type="button"
                data-toggle="collapse"
                data-target="#navbarNav"
                aria-controls="navbarNav"
                aria-expanded="false"
                aria-label="Toggle navigation"
            >
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav ml-auto">
                    <li class="nav-item active">
                        <a class="nav-link" href="#">Home<span> / </span><span class="sr-only">(current)</span></a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#past-bookings">Archive<span> / </span></a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">About<span> / </span></a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#subscribe">Newsletter<span> / </span></a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="mailto: [email protected]">Contact</a>
                    </li>
                </ul>
                <ul class="nav navbar-nav flex-row justify-content-center flex-nowrap">
                    <li class="nav-item">
                        <a
                            class="nav-link nav-social-icon"
                            target="_blank"
                            href="https://www.facebook.com/GetMove.Official/"
                            ><i class="fab fa-facebook-square"></i
                        ></a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link nav-social-icon" target="_blank" href="https://www.instagram.com/getmovemx/"
                            ><i class="fab fa-instagram"></i
                        ></a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link nav-social-icon" target="_blank" href="https://soundcloud.com/getmove"
                            ><i class="fab fa-soundcloud"></i
                        ></a>
                    </li>
                </ul>
            </div>
        </nav>

CSS

.nav-item:after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    width: 0%;
    border-bottom: 1px solid black;
    transition: 0.4s;
}

.nav-item:hover:after {
    width: 100%;
}

Fiddle here https://codepen.io/pen/WNNPdxv

like image 318
octavemirbeau Avatar asked Mar 31 '26 19:03

octavemirbeau


1 Answers

To solve this issue you should not put separators inside the anchor elements. Below is an approach which eliminates the extra HTML using the content property. This is similar to Bootstrap's breadcrumb.

But as you're already familiar, first some cleanup ^^

  • remove the span separators from nav-links
  • use the span for text nodes (could be handy to put the animation on there)
  • move the animation from :after to :before (a separator is logically after an element, except for the last-child perhaps, this also gives you the elements width where you can now control the right position.)
  • use the :after for the separator
  • provide full width for the main navigation and use flexbox to align the space it's using (flex-end, center, space-between, ...)

HTML changes

<div class="collapse navbar-collapse" id="navbarNav">
    <ul class="nav navbar-nav navbar-primary w-100 ml-auto">
        <li class="nav-item active">
            <a class="nav-link" href="#">
                <span>Home</span>
                <span class="sr-only">(current)</span>
            </a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="#past-bookings"><span>Archive</span></a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="#"><span>About</span></a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="#subscribe"><span>Newsletter</span></a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="mailto: [email protected]"><span>Contact</span></a>
        </li>
    </ul>
    <ul class="nav navbar-nav navbar-secondary flex-row justify-content-center flex-nowrap">
        <li class="nav-item">
            <a class="nav-link nav-social-icon" target="_blank" href="https://www.facebook.com/GetMove.Official/"><i class="fa fa-facebook-square"></i></a>
        </li>
        <li class="nav-item">
            <a class="nav-link nav-social-icon" target="_blank" href="https://www.instagram.com/getmovemx/"><i class="fa fa-instagram"></i></a>
        </li>
        <li class="nav-item">
            <a class="nav-link nav-social-icon" target="_blank" href="https://soundcloud.com/getmove"><i class="fa fa-soundcloud"></i></a>
        </li>
    </ul>
</div>

Solution

Now to solve the issue, place the animation on before and separator on the after pseudo elements.

.navbar-primary .nav-item:after {
    content: "/";
    position: absolute;
    top: 0.25rem;
    left: auto;
    right: -0.5rem; /* control the amount of space for the separator */
}

.navbar-primary .nav-item:before {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    width: 0%;
    border-bottom: 1px solid black;
    transition: 0.4s;
}

.navbar-primary .nav-item:hover:before {
    width: 100%;
} 

In case you want to change the character, you have only one editing place.

DEMO

In case you want to change the animation without the padding I'd suggest to distract the nav-link padding using calc().

.navbar-primary .nav-link:before {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0.5rem; /* nav-link padding-left */
    width: 0%;
    border-bottom: 1px solid black;
    transition: 0.4s;
}

.navbar-primary .nav-link:hover:before {
    width: calc(100% - 1rem); /* minus nav-link padding left and right */
}

DEMO

like image 181
Tim Vermaelen Avatar answered Apr 03 '26 10:04

Tim Vermaelen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!