Home > Software design >  Improve Bootstrap parallelogram navbar menu by making menu items flush
Improve Bootstrap parallelogram navbar menu by making menu items flush

Time:09-30

I'm trying to adapt Bootstrap 5's navbar menu into a rollover menu with a parallelogram-shaped active menu item, using the menu bar example, active state on

Here is a CodePen reproducing the problem and containing all the relevant code.

Markup since apparently it's a requirement even when including a CodePen:

.navbar {
  padding-top: 0;
}

.navbar-nav {
  display: table;
  width: 100%;
}

.navbar-nav>li {
  float: none;
  display: table-cell;
  text-align: center;
  transform: skewX(-40deg);
  -o-transform: skewX(-40deg);
  -moz-transform: skewX(-40deg);
  -webkit-transform: skewX(-40deg);
}

.navbar-nav>li span {
  display: inline-block;
  transform: skewX(40deg);
  -o-transform: skewX(40deg);
  -moz-transform: skewX(40deg);
  -webkit-transform: skewX(40deg);
}

.navbar-nav .show>.nav-link,
.navbar-nav .nav-link {
  color: #000;
  transition: all 350ms ease-out;
  -webkit-transition: all 350ms ease-out;
  -moz-transition: all 350ms ease-out;
  -o-transition: all 350ms ease-out;
}

.navbar-nav .active {
  color: #FFF;
  background: #000;
}

.navbar-nav .nav-link:hover {
  color: #FFF;
  background: #000;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet"/>
<nav class="navbar navbar-expand-lg collapsed" aria-label="Eighth navbar example">
  <div class="container">
    <a class="navbar-brand me-6 me-xl-7" href="#">Brand</a>
    <button class="navbar-toggler third-button" type="button" data-bs-toggle="collapse" data-bs-target="#navbar-home" aria-controls="navbarsExample07" aria-expanded="false" aria-label="Toggle navigation">
                <div class="animated-icon">
                    <span></span>
                    <span></span>
                    <span></span>
                </div>
            </button>

    <div class="collapse navbar-collapse" id="navbar-home">
      <ul class="navbar-nav mb-auto mb-2 my-0 mb-lg-0">
        <li class="nav-item">
          <a class="nav-link active" aria-current="page" href="#"><span>Home</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link active" href="#"><span>Find My Car</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link active" href="#"><span>Frequently Asked Questions</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link active" href="#"><span>Testimonials</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link active" href="#"><span>Contact Us</span></a>
        </li>
      </ul>
    </div>
  </div>
</nav>

Why are my menu items refusing to be flush and how can I make them so?

CodePudding user response:

They probably are 'flush' i.e. next to each other as far as CSS is concerned - what I am seeing is varying white between different items which change when the zoom level changes - I think it's part-pixels (in CSS terms) - a CSS pixel can consist of several screen pixels so you get edge effects - rounding errors basically.

One, slightly hacky, way round this is to put a pseudo element on each item which is 1px (CSS pixel i.e.) bigger all round than the item and has the same color background. This disguises the edge effect. This snippet adds this code to the code given in the question's codepen:

.navbar-nav .active::before {
  content: '';
  background-color: #000;
  position: absolute;
  width: calc(100%   2px);
  height: calc(100%   2px);
  top: -1px;
  left: -1px;
  display: inline-block;
}

<html lang="en">

<head>

  <meta charset="UTF-8">

  <link rel="apple-touch-icon" type="image/png" href="https://cpwebassets.codepen.io/assets/favicon/apple-touch-icon-5ae1a0698dcc2402e9712f7d01ed509a57814f994c660df9f7a952f3060705ee.png">
  <meta name="apple-mobile-web-app-title" content="CodePen">

  <link rel="shortcut icon" type="image/x-icon" href="https://cpwebassets.codepen.io/assets/favicon/favicon-aec34940fbc1a6e787974dcd360f2c6b63348d4b1f4e06c77743096d55480f33.ico">

  <link rel="mask-icon" type="" href="https://cpwebassets.codepen.io/assets/favicon/logo-pin-8f3771b1072e3c38bd662872f6b673a722f4b3ca2421637d5596661b4e2132cc.svg" color="#111">


  <title>CodePen - A Pen by Hashim</title>


  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css">

  <style>
    .navbar {
      padding-top: 0;
    }
    
    .navbar-nav {
      display: table;
      width: 100%;
    }
    
    .navbar-nav>li {
      float: none;
      display: table-cell;
      text-align: center;
      transform: skewX(-40deg);
      -o-transform: skewX(-40deg);
      -moz-transform: skewX(-40deg);
      -webkit-transform: skewX(-40deg);
    }
    
    .navbar-nav>li span {
      display: inline-block;
      transform: skewX(40deg);
      -o-transform: skewX(40deg);
      -moz-transform: skewX(40deg);
      -webkit-transform: skewX(40deg);
    }
    
    .navbar-nav .show>.nav-link,
    .navbar-nav .nav-link {
      color: #000;
      transition: all 350ms ease-out;
      -webkit-transition: all 350ms ease-out;
      -moz-transition: all 350ms ease-out;
      -o-transition: all 350ms ease-out;
    }
    
    .navbar-nav .active {
      color: #FFF;
      background: #000;
      position: relative;
    }
    
    .navbar-nav .nav-link:hover {
      color: #FFF;
      background: #000;
    }
    
    .navbar-nav .active::before {
      content: '';
      background-color: #000;
      position: absolute;
      width: calc(100%   2px);
      height: calc(100%   2px);
      top: -1px;
      left: -1px;
      display: inline-block;
    }
  </style>

  <script>
    window.console = window.console || function(t) {};
  </script>



  <script>
    if (document.location.search.match(/type=embed/gi)) {
      window.parent.postMessage("resize", "*");
    }
  </script>


</head>

<body translate="no">
  <nav class="navbar navbar-expand-lg collapsed" aria-label="Eighth navbar example">
    <div class="container">
      <a class="navbar-brand me-6 me-xl-7" href="#">Brand</a>
      <button class="navbar-toggler third-button" type="button" data-bs-toggle="collapse" data-bs-target="#navbar-home" aria-controls="navbarsExample07" aria-expanded="false" aria-label="Toggle navigation">
            <div class="animated-icon">
                <span></span>
                <span></span>
                <span></span>
            </div>
        </button>

      <div class="collapse navbar-collapse" id="navbar-home">
        <ul class="navbar-nav mb-auto mb-2 my-0 mb-lg-0">
          <li class="nav-item">
            <a class="nav-link active" aria-current="page" href="#"><span>Home</span></a>
          </li>
          <li class="nav-item">
            <a class="nav-link active" href="#"><span>Find My Car</span></a>
          </li>
          <li class="nav-item">
            <a class="nav-link active" href="#"><span>Frequently Asked Questions</span></a>
          </li>
          <li class="nav-item">
            <a class="nav-link active" href="#"><span>Testimonials</span></a>
          </li>
          <li class="nav-item">
            <a class="nav-link active" href="#"><span>Contact Us</span></a>
          </li>
        </ul>
      </div>
    </div>
  </nav>









</body>

</html>

Run the snippet in full page and alter the zoom level to check that no spurious white 'dividing line' is appearing.

CodePudding user response:

In the end I decided to solve this by using a different method and then adding margin-left:-2px, which integrates much better with the Bootstrap navbar than the old solution did. The markup remains the exact same, and below is my CSS:

@media (min-width: 992px) {

  .navbar-nav .nav-item .nav-link {
    padding-right: 0.3em;
    padding-left: 0.3em;
  }

  .navbar-nav {
    display:table; 
    width:100%;
  }

  .navbar li {
    display: table-cell;
  }

  .navbar-nav .nav-item {
    float: left;
    padding-right: 1em;
    padding-left: 1em;
    position: relative;
    cursor: pointer;
    margin-left: -2px;
  }

  .navbar-nav .nav-item::after {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    z-index: -1;
    transform: skew(-45deg);
    transition: background-color 100ms ease-in-out, border-color 100ms ease-in-out;
  }

  .navbar-nav .nav-item .active::after {
    background-color: var(--bs-body-color);
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    z-index: -1;
    transform: skew(-45deg);
    transition: background-color 100ms ease-in-out, border-color 100ms ease-in-out;
  }

  .navbar-nav .nav-item .nav-link {
    color: var(--bs-body-colour);
    transition: none;
  }

  .navbar-nav .nav-item .active,
  .navbar-nav .nav-item .nav-link:hover {
    color: var(--bs-body-bg);
  }

  .navbar-nav .nav-item:hover::after {
    background-color: var(--bs-body-color);
    color: var(--bs-body-bg);
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    z-index: -1;
    transform: skew(-45deg);
    transition: background-color 100ms ease-in-out, border-color 100ms ease-in-out;
  }
}

Notice that I placed it all inside of the md media-query to ensure it applies only to all devices that are larger, preventing it from interfering with the navbar on non-mobile devices.

  • Related