octavemirbeau
octavemirbeau

Reputation: 507

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

Upvotes: 3

Views: 9136

Answers (2)

Tim Vermaelen
Tim Vermaelen

Reputation: 7059

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

Upvotes: 1

vidgarga
vidgarga

Reputation: 330

You should put the hover on the a-link, and then a-link position:relative, or put the class position-relative to the a-link.

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

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

Upvotes: 0

Related Questions