"Transforming your menu into a fully responsive Bootstrap menu: a step-by

Struggling to implement a responsive and animated Bootstrap 5 menu in this Codepen example. Tinkered with a few things, but it always seems to break one way or another.

Check out the example here

Looking to swap out the current menu with a Bootstrap menu that is responsive and features hover animations for larger screens.

<nav class="navbar navbar-expand-lg navbar-light p-5">
            <div class="container">
              <a class="navbar-brand" href="#"><img class="img-fluid" src="images/logo.png"/></a>
              <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-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">
                  <li class="nav-item">
                    <a class="nav-link active" aria-current="page" href="#">Home</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="#">Offers</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="#">Pricing</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
                  </li>
                </ul>
              </div>
            </div>
          </nav>

Answer №1

Check out this Bootstrap 5.0 page layout with the navbar featuring a centered logo for larger screens.

Updated Version

In my original response, I used a bit of a workaround by incorporating two logos – one for mobile and another for larger displays in order to achieve equal spacing around the four links and the logo, as requested. However, this led to redundant content.

For the updated version, I opted for a single logo and divided the links between two navbar-collapse lists. By splitting the links into separate lists, it allowed placement for the logo in the center on bigger screens. Using order: 2, I positioned the logo from the left on small screens to the middle on wider screens.

The navbar-collapse divs are set to expand and fill the available space using flex-grow-1. The ul lists within these divs are styled with w-100 and justify-content-evenly to evenly space out the links.

As there are two navbar-collapse divs now, I modified the navbar-toggler button to utilize a class value for data-bs-target instead of an id. Additionally, I listed the ids for the two navbar-collapse divs in the

aria-controls="navbarContent1 navbarContent2"
attribute with a space separating the two.

While the focus was initially on aligning a Bootstrap 5 navbar to match a specific example, I also made adjustments for the Green Sock animation (GASP):

  • Implemented listeners for load, resize, orientation changes to configure or reconfigure the GASP setup.
  • Transitioned from using innerWidth to document.documentElement.clientWidth – innerWidth includes the scrollbar width, which can shift elements if present. clientWidth avoided this issue.
  • Refined the svg path for the blob element for smoother animation.

const nav = document.querySelector(".navbar");
const blob = document.querySelector("svg.nav-blob");

function initiateBlob() {
    gsap.set(blob, {
        xPercent: -50,
        x: document.documentElement.clientWidth / 2
    });
}

nav.addEventListener("mousemove", function(e) {
    gsap.to(blob, {
        duration: 0.2,
        x: e.clientX,
        overwrite: 'auto'
    });
});
nav.addEventListener("mouseleave", function(e) {
    gsap.to(blob, {
        duration: 0.1,
        x: document.documentElement.clientWidth / 2,
        overwrite: 'auto'
    });

});

window.addEventListener('load', initiateBlob, false);
window.addEventListener('resize', initiateBlob, false);
window.addEventListener('orientationchange', initiateBlob, false);
Your CSS code here...

Your additional HTML markup goes here...

I've replaced the previous images with equally sized placeholder images.

The concept of handling separate menu items for the mobile menu was inspired by a solution provided for a different query on Stack Overflow: Bootstrap 4 navbar with brand center and links on the left, center and right

Answer №2

If you want to customize your navigation for desktop and mobile separately, take a look at the code snippet provided below.

Feel free to thank me later.

console.clear();
  const nav  = document.querySelector(".nav-container");
  const blob = document.querySelector(".nav-container svg");
  
  gsap.set(blob, {xPercent: -50, x:innerWidth / 2});
  
  nav.addEventListener("mousemove", function(e){
    gsap.to(blob, {duration: 0.2, x: e.clientX, overwrite: 'auto'});
  });
    nav.addEventListener("mouseleave", function(e){
    gsap.to(blob, {duration:0.1, x: innerWidth / 2, overwrite: `auto`});
    
  });
body{font-family: "Open Sans Condensed"; background: black;}
  h1 {font-family: "Open Sans Condensed"; font-size: 2.2em; font-weight: 600;}
  .c-hotel  h3 {font-size: 1.2em; font-weight: 600;}
  .logo {max-width: 160px;}

  .nav-container nav {
    display: flex;
    justify-content: space-around;
    background:white;
    height:100px;
  }
  .nav-container nav a {
    color: black;
    text-decoration: none;
    font-size: 20px;
    font-family:"Roboto";
    font-weight: 600;
    color: #358E9D;
    text-transform: uppercase;
    padding: 10px 20px 20px 20px;
    line-height: 70px;
  }
  .nav-container{position: relative;}
  .nav-container svg{
    position: absolute;
    top:100%;
    left:0;
    height:20px;
    z-index: 1;
  }
  .nav-container path{
    fill:white;

  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.0/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="063448465d13551e00580215614550546046497b18151515132c57505504">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="264546565b454542414054335651635451477b06242908">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Open+Sans+Condensed:wght@300&family=Roboto:wght@300&display=swap" rel="stylesheet">

<div class="containerx nav-container">
  <nav class="d-none d-lg-block">
    <a href="#">HOME</a>
    <a href="#">DINE</a>
    <a href="#"><img class="img-fluid logo" src="https://dummyimage.com/200x70/b59ab5/fff.png&text=LOGO" /></a>
    <a href="#">HOTELS</a>
    <a href="#">CONTACT</a>
  </nav>
  <svg viewBox="0 0 200 20">
    <path class="blob" d="M0 0 C60 0 60 18 100 18 C140 18 120 0 200 0 Z"></path>
  </svg>
</div>

<!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
<nav class="navbar d-lg-none navbar-expand-lg navbar-light p-5">
            <div class="container">
              <a class="navbar-brand" href="#"><img class="img-fluid" src="images/logo.png" alt="Logo"/></a>
              <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-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">
                  <li class="nav-item">
                    <a class="nav-link active" aria-current="page" href="#">Home</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="#">DONE</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="#">HOTELS</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="#">Contact</a>
                  </li>
                </ul>
              </div>
            </div>
          </nav>

<div class="container-fluid mb-3 mt-0 p-0">
  <div class="row gx-0">
    <div class="col-lg-6 col-md-6 mb-sm-4 mb-md-0 mb-lg-0 border-0">
      <div class="card bg-dark text-white text-center shadow-sm  rounded-0">
        <img src="https://www.arabnews.com/sites/default/files/styles/n_670_395/public/2020/05/13/2103246-1947731261.jpg?itok=CYsgY2Qi" class="card-img" alt="...">
        <div class="card-img-overlay d-flex align-items-center">
          <h2 class="card-title text-center w-100 "> HEADING ONE</h2>
        </div>
      </div>
    </div>
    <div class="col-lg-6 col-md-6">
      <div class="card bg-dark text-white text-center shadow-sm  rounded-0 border-0">
        <img src="https://www.arabnews.com/sites/default/files/styles/n_670_395/public/2020/05/13/2103246-1947731261.jpg?itok=CYsgY2Qi" class="card-img" alt="...">
        <div class="card-img-overlay">
          <h2 class="card-title">HEADING TWO</h2>
          <!-- <p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p> -->
        </div>
      </div>
    </div>
  </div>
</div>

Answer №3

Perhaps this information could be of assistance

  • I included jQuery & CSS in media(767px)

  • I created an animated popup menu when the menu bar is clicked.

  • Your navbar HTML structure isn't suitable for making a responsive menu, so I added an extra menu for mobile to make it responsive.

console.clear();
  const nav = document.querySelector(".nav-container");
  const blob = document.querySelector(".nav-container svg");

  gsap.set(blob, { xPercent: -50, x: innerWidth / 2 });

  nav.addEventListener("mousemove", function (e) {
    gsap.to(blob, { duration: 0.2, x: e.clientX, overwrite: "auto" });
  });
  nav.addEventListener("mouseleave", function (e) {
    gsap.to(blob, { duration: 0.1, x: innerWidth / 2, overwrite: `auto` });
  });

  window.onresize = function () {
    gsap.set(blob, { xPercent: -50, x: innerWidth / 2 });

    nav.addEventListener("mousemove", function (e) {
      gsap.to(blob, { duration: 0.2, x: e.clientX, overwrite: "auto" });
    });
    nav.addEventListener("mouseleave", function (e) {
      gsap.to(blob, { duration: 0.1, x: innerWidth / 2, overwrite: `auto` });
    });
  };
  
  /*****For menu open*******/
  $(document).ready(function () {
    $('.menu-btn').click(function(event) {
      $('.navbar-demo').toggleClass('open-nav');
    });
  });
... (More code follows)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Optimal Timing for Loading Initial State from Database Using Vuex

In my Vue/Vuex project, I have a simple setup where I retrieve a list of categories from my database using an HTTP GET request. Before implementing Vuex, I used to fetch this data directly in my main component when it was created. Now with Vuex, I have g ...

The visibility of a password input in HTML

I have a question regarding changing an input tag of type password to an input type like visible-password. Instead of changing it to type text, I want to keep it as a type password but with the CSS rule like this: -webkit-text-security: none !important; ...

What's the reason behind the absence of applied bootstrap style in jsFiddle?

Link to the code: Click here I'm having trouble understanding why the default style of <ol> from Bootstrap is not being applied in this particular code. Any insights? Here's a snippet of the HTML code taken from the fiddle. <ul> ...

jQuery sends ajax success to input type number

I am encountering an issue with the ajax success loading function when using input type number. Interestingly, when I switch the input type to text, it works perfectly fine. However, once I change the input type back to number, the loading ceases. <s ...

Issue encountered when trying to test a slider element using TestCafe

Could someone please help me with writing a test for a slider element in this situation? <Slider defaultValue={pickupValue.length ? pickupValue : [15, 15]} aria-labelledby="range-slider" ...

Font may seem more slender in Firefox and Safari compared to Chrome where the appearance is impeccable

I am currently working on achieving consistent font appearance across Mac Chrome, Safari, and Firefox (IE compatibility to be addressed later). My experiments have included: -webkit-font-smoothing: subpixel-antialiased; The font appears almost identica ...

Having trouble with sending an ajax PUT request

UPDATE: The issue of getting an undefined URI was resolved by storing $(this).attr('red') in a variable. However, the 500 Server error persists. UPDATE: For reference, the complete code can be found on GitHub. Just to ensure nothing was overlook ...

Reducing image file sizes in Ionic 3

I have been struggling to compress an image client-side using Ionic 3 for the past couple of days. I have experimented with: ng2-img-max - encountered an error when utilizing the blue-imp-canvas-to-blob canvas.toBlob() method (which is a dependency of ng2 ...

Grunt integration for version control

After sticking to simple Html and Css for the longest time, I'm finally diving into JavaScript for a new project where I want to automate versioning. I've been following the SemVer Guidelines and my projects are currently versioned as "version": ...

Adding text over an image in Tailwind without the need for absolute positioning is achievable

I'm struggling to position text over an image without using absolute positioning. It's working fine on large and small screens, but I'm having trouble with medium screens. I've searched for similar questions on Stack Overflow, but none ...

Incorporating video.js into an Angular website application

I've encountered a strange issue while attempting to integrate video.js into my angular app. <video id="example_video_1" class="video-js vjs-default-skin" controls preload="none" width="300" height="264" poster="http://video-js.zenco ...

execute a function upon selecting a radio button

Below is the HTML code that includes two radio buttons. The default checked button is the "lease" option. <input id="quotation_request_payment_option_lease" class="choose_payment_option" name="quotation_request[payment_option]" type ...

Exploring JavaScript and mastering it through Visual Studio Code and Node.js for debugging and learning

I am currently using Visual Studio Code to practice and test my Javascript skills. In order to activate debugging features, I have installed Node.js and selected "node" in the launch.json file. What's confusing me is that the outcome of my code seem ...

Is it possible to create a Bootstrap 4 Modal using JQuery and AJAX?

Currently, I have a form enclosed within a modal, and I am struggling to extract the data from the modal for use in other parts of my application. Despite attempting to follow JQuery and AJAX tutorials to handle the data, I have been unsuccessful in getti ...

What causes the variation in table border display between Firefox, IE, and Chromium browsers?

I am utilizing Datatables to display a data table. Although it works correctly, Firefox shows a thicker border after every n rows : Is this a "Firefox feature" designed to make tables more readable? Or could it possibly be a CSS bug? Upon inspecting wi ...

How is it possible to receive a TRUE value when the API returns an error message indicating that the requested photo does not exist?

I am currently in the process of learning Angular and Typescript, but I am facing some challenges. I am working on an application that involves displaying a list of photos, as well as allowing users to create, edit, and delete existing photos. However, whe ...

Trouble with pinch zoom functionality in a Vue component

I have a Vue component that allows me to zoom in on an image using the mouse wheel, but I'm experiencing strange behavior with pinch zoom. When I place two fingers far apart on the screen, it zooms in significantly, and when I bring them closer togeth ...

The accuracy of getBoundingClientRect in calculating the width of table cells (td)

Currently, I am tackling a feature that necessitates me to specify the CSS width in pixels for each td element of a table upon clicking a button. My approach involves using getBoundingClientRect to compute the td width and retrieving the value in pixels (e ...

Issue with form array patching causing value not to be set on material multiple select

When attempting to populate a mat-select with multiple options using an array of ids from Firestore, I encountered an issue. The approach involved looping through the array, creating a new form control for each id, and then adding it to the formArray using ...

The functionality of Next.JS Cpanel Deployment Server.js appears to be malfunctioning

Trying to deploy my website on cpanel, I am utilizing a node.js application with cpanel. Here is the configuration: https://i.sstatic.net/AXap3.png However, when I start my server, it displays "503 service unavailable." https://i.sstatic.net/17JAu.png ...