Search code examples
htmljquerycssbootstrap-4scroll

How can I create a shrinking header with a shadow effect on scroll using Bootstrap and jQuery?


I'm working on a webpage using Bootstrap 4 and jQuery, and I want to create a header that shrinks in size and adds a shadow effect when the user scrolls down the page. I've written some code that mostly works, but I'm not getting the smooth transition I want, and the shadow effect isn't consistent.

Problem:

. The header and logo should shrink when scrolling down. . A shadow should appear under the header during the scroll. . The transition should be smooth, but mine feels choppy.

Here's the HTML, CSS, and JavaScript code I've been working with:

<nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top">
    <div class="container">
        <a class="navbar-brand" href="#">
            <h6 id="logo" class="display-7 font-weight-bold text-dark">
                Mahyar<br>ART<br>GALERIE
            </h6>
        </a>
        <button class="navbar-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"><a class="nav-link" href="#">Home</a></li>
                <li class="nav-item"><a class="nav-link" href="#">About</a></li>
                <li class="nav-item"><a class="nav-link" href="#">Services</a></li>
                <li class="nav-item"><a class="nav-link" href="#">Contact</a></li>
            </ul>
        </div>
    </div>
</nav>

css:

#logo {
    font-size: 2.5rem;
    transition: font-size 0.3s ease-in-out, padding 0.3s ease-in-out;
    padding: 10px 0;
}

.shrink #logo {
    font-size: 1.5rem;
    padding: 5px 0;
}

.navbar {
    transition: padding 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
    padding: 20px 0;
}

.shrink .navbar {
    padding: 10px 0;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

JS :

#logo {
    font-size: 2.5rem;
    transition: font-size 0.3s ease-in-out, padding 0.3s ease-in-out;
    padding: 10px 0;
}

.shrink #logo {
    font-size: 1.5rem;
    padding: 5px 0;
}

.navbar {
    transition: padding 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
    padding: 20px 0;
}

.shrink .navbar {
    padding: 10px 0;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

My Issue:

The transition isn't as smooth as I'd like, especially when viewed on slower devices. The shadow effect under the header sometimes doesn't appear correctly or flickers. What I've Tried:

I've adjusted the transition timing but still experience choppiness. I've tested on different browsers, but the shadow issue persists. Question: How can I make the transition smoother and ensure the shadow effect appears consistently across different devices and browsers?


Solution

  • You didn't share the Javascript code you used to set/unset the shrink class when the scroll event occurs.

    So it's not clear what's the actual behaviour you are experiencing as a way of comparison with any proposed solution.

    By the way since you already had the css transitions defined, I just changed one selector to better match the logo and added a minimum javascript needed to add/remove the shrink class to the .navbar element.

    It works correctly according to the expectation:

    //on DOM ready
    $(document).ready(function() {
      //adds the window scroll event handler
      $(window).scroll(function() {
        //that will add/remove the shrink class to the .navbar according to the scrollbar relative to threshold
        const threshold = 50;
        if ($(this).scrollTop() > threshold) { 
          $('.navbar').addClass('shrink');
        } else {
          $('.navbar').removeClass('shrink');
        }
      });
    });
    #logo {
      font-size: 2.5rem;
      transition: font-size 0.3s ease-in-out, padding 0.3s ease-in-out;
      padding: 10px 0;
    }
    
    .shrink #logo{
      font-size: 1.5rem;
      padding: 5px 0;
    }
    
    .navbar {
      transition: padding 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
      padding: 20px 0;
    }
    
    .navbar.shrink {
      padding: 10px 0;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    }
    
    section {
      height: 2000px;
    }
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap.min.css" integrity="sha512-rt/SrQ4UNIaGfDyEXZtNcyWvQeOq0QLygHluFQcSjaGB04IxWhal71tKuzP6K8eYXYB6vJV4pHkXcmFGGQ1/0w==" crossorigin="anonymous" referrerpolicy="no-referrer"
    />
    
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.bundle.min.js"></script>
    
    <nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top">
      <div class="container">
        <a class="navbar-brand" href="#">
          <h6 id="logo" class="display-7 font-weight-bold text-dark">
            Mahyar<br>ART<br>GALERIE
          </h6>
        </a>
        <button class="navbar-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"><a class="nav-link" href="#">Home</a></li>
            <li class="nav-item"><a class="nav-link" href="#">About</a></li>
            <li class="nav-item"><a class="nav-link" href="#">Services</a></li>
            <li class="nav-item"><a class="nav-link" href="#">Contact</a></li>
          </ul>
        </div>
      </div>
    </nav>
    
    <section>
      ...PAGE CONTENT...
    </section>