Bootstrap 4 - Fullscreen mobile navbar

£可爱£侵袭症+ 提交于 2020-04-05 12:31:41

问题


I'm trying to figure out how I can do a fullscreen menu (navbar) on mobile size, with this I mean that when you press on the 'hamburger-menu' the navbar (with the items) should occupy all the viewport.

I achieved this just writing:

#navbarText{
  height: 100vh;
}

But the bootstrap animation isn't smooth like the default one, as you can see here (normally the animation increase the div size gradually and vice-versa when you close it):

Here the code:

/*---Standar Hamburger Menu (3 separate elements)---*/

.navbar-toggler {
  border: none;
  background: transparent !important;
}

.navbar-toggler:hover {
  background: transparent !important;
}

.navbar-toggler .icon-bar {
  height: 2px;
  width: 22px;
  border-radius: 1px;
  display: block;
  background-color: #B6B6B6;
  -webkit-transition: all 0.2s;
  transition: all 0.2s;
}

.navbar-toggler .icon-bar+.icon-bar {
  margin-top: 4px;
}


/*---Animation menu (create X)---*/

.navbar-toggler.x .icon-bar:nth-of-type(1) {
  -webkit-transform: translateX(3px) rotate(45deg);
  /* Safari 3-8 & Chrome 4-35 & Opera 15-22 */
  -ms-transform: translateX(3px) rotate(45deg);
  /* IE 9 */
  -moz-transform: translateX(3px) rotate(45deg);
  /* Firefox 3-15 */
  -o-transform: translateX(3px) rotate(45deg);
  /* Opera 10-14 */
  transform: translateX(3px) rotate(45deg);
  -webkit-transform-origin: 10% 10%;
  -ms-transform-origin: 10% 10%;
  -moz-transform-origin: 10% 10%;
  -o-transform-origin: 10% 10%;
  transform-origin: 10% 10%;
}

.navbar-toggler.x .icon-bar:nth-of-type(2) {
  opacity: 0;
  filter: alpha(opacity=0);
  /* For IE8 and earlier */
  -moz-opacity: 0;
  /* Older Firefox 1 */
}

.navbar-toggler.x .icon-bar:nth-of-type(3) {
  -webkit-transform: translateX(3px) rotate(-45deg);
  -ms-transform: translateX(3px) rotate(-45deg);
  -moz-transform: translateX(3px)rotate(-45deg);
  -o-transform: translateX(3px) rotate(-45deg);
  transform: translateX(3px) rotate(-45deg);
  -webkit-transform-origin: 10% 90%;
  -ms-transform-origin: 10% 90%;
  -moz-transform-origin: 10% 90%;
  -o-transform-origin: 10% 90%;
  transform-origin: 10% 90%;
}

.navbar-toggler.x.collapsed .icon-bar:nth-of-type(1) {
  -webkit-transform: rotate(0);
  -ms-transform: rotate(0);
  -moz-transform: rotate(0);
  -o-transform: rotate(0);
  transform: rotate(0);
}

.navbar-toggler.x.collapsed .icon-bar:nth-of-type(2) {
  opacity: 1;
  filter: alpha(opacity=100);
  -moz-opacity: 1;
}

.navbar-toggler.x.collapsed .icon-bar:nth-of-type(3) {
  -webkit-transform: rotate(0);
  -ms-transform: rotate(0);
  -moz-transform: rotate(0);
  -o-transform: rotate(0);
  transform: rotate(0);
}


/*---To center elements of the navbar (mobile)---*/

.navbar-brand {
  font-size: 1rem;
}


/*---Custom AnimateCSS mobile menu items---*/

.nav-item {
  -webkit-animation-duration: 0.8s;
  /* Chrome 3-42 & Safari 4-8 & Opera 15-29 */
  -moz-animation-duration: 0.8s;
  /* Firefox 5-15 */
  -o-animation-duration: 0.8s;
  /* Opera 12-14 */
  animation-duration: 0.8s;
}

@media only screen and (max-width: 991px) {
  #navbarText {
    height: 100vh !important;
  }
}

@media only screen and (min-device-width: 992px) {
  .animated {
    /*CSS transitions*/
    -o-transition-property: none !important;
    -moz-transition-property: none !important;
    -ms-transition-property: none !important;
    -webkit-transition-property: none !important;
    transition-property: none !important;
    /*CSS transforms*/
    -o-transform: none !important;
    -moz-transform: none !important;
    -ms-transform: none !important;
    -webkit-transform: none !important;
    transform: none !important;
    /*CSS animations*/
    -webkit-animation: none !important;
    -moz-animation: none !important;
    -o-animation: none !important;
    -ms-animation: none !important;
    animation: none !important;
  }
  #navbarText {
    height: auto;
  }
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>HOME</title>


  <!-- TODO add manifest here -->

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
  <link href="https://fonts.googleapis.com/css?family=Montserrat:200" rel="stylesheet">

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

  <link rel="stylesheet" type="text/css" href="style.css">

  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>
  <nav class="navbar navbar-expand-lg sticky-top navbar-dark bg-dark">
    <div class="d-flex align-items-center justify-content-between w-100">
      <button class="navbar-toggler navbar-toggler-left x collapsed" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
              </button>
      <a class="navbar-brand mx-auto ml-lg-5" href="#">
        <img src="https://getbootstrap.com/assets/brand/bootstrap-solid.svg" width="30" height="30" alt="Logo">
      </a>
    </div>
    <div class="collapse navbar-collapse mr-lg-5" id="navbarText">
      <ul class="navbar-nav ml-auto">
        <li class="nav-item active mx-2 animated fadeInDown">
          <a class="nav-link" href="#">HOME<span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item mx-2 animated fadeInDown">
          <a class="nav-link" href="#">PROJECTS</a>
        </li>
        <li class="nav-item mx-2 animated fadeInDown">
          <a class="nav-link" href="#">ABOUT</a>
        </li>
        <li class="nav-item mx-2 animated fadeInDown">
          <a class="nav-link" href="#">CONTACT</a>
        </li>
      </ul>
    </div>
  </nav>
  <div>
    <p>Test</p>
  </div>
  <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  <p>ffff</p>
</body>

</html>

Do you know a way to fix it??

If you want to edit/test the code I also leave a link to Codeply


回答1:


In your code you have done some impressive amount of work. I haven't gone through the whole code, instead I just added the following css:

.navbar-nav {
  height: 100vh !important;
}

This will work on any bootstrap 4 project as Bootstrap 4 stands today. Below is a pic of sample code with the highlighted class that I have modified, doing the same should work for most people and give the smooth transition from bootstrap without wanting to use JS or modify anything major.

Hope it helps everyone.




回答2:


I looked at the Bootstrap JS file and I find out that to achieve this effect you just need to change a few lines, to be more specific, where it's defined the 'Collapse' function (more or less at the 1100th line). The changes are:

Object.defineProperty(this._element, 'scrollHeight', {
      writable: true,
      value: $(window).height()-$(".navbar").outerHeight()
});

Placed after the assignment state of the this._element variable. With this we are defining the maximum size of the '.navbar-collapse' div, and that's why we are also subtract $(".navbar").outerHeight() value (the value it's referred at the initial moment, so when the menu still hidden, so with this we subtract the .navbar-brand div's height and the eventual parent's padding/margin).

We need to do in this way, because the 'scrollHeight' property (and also the others) isn't modifiable by default so we need to specify it.

The last change is to remove the line

_this._element.style[dimension] = '';

We do so, because otherwise when the element has the 'show' attribute (it has finished the animation) it won't occupy all the screen, basically since this line remove our custom height.

With these few changes we achieve the wanted result, the only cons of this solution is that we lose the capability of using the CDN for this file, because we need to download it and change it.

To be clear, this should be the file after the changes:

 ...
 var Collapse = function () {
  function Collapse(element, config) {
    ...
    this._element = element;
    //CHANGE (1)
    Object.defineProperty(this._element, 'scrollHeight', {
      writable: true,
      value: $(window).height()-$(".navbar").outerHeight()
    });
    this._config = this._getConfig(config);
    ...
  }
  ...
  _proto.show = function show() {
    var complete = function complete() {
      ...
      /* CHANGE (2) - Remove
      _this._element.style[dimension] = ''; */

      ...
    };
  };
  ...
 }
 ...


来源:https://stackoverflow.com/questions/48892380/bootstrap-4-fullscreen-mobile-navbar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!