11

Thank you for considering this question.

The code can be found on GitHub, here.

There are a few things going on here, so before we get to the code I want explain a bit about it.

I have a function makeNavigation that takes three parameters to make the navigation bar: an array of items for the navigation bar, the element id of where the navigation bar should go, and a size.

This works pretty well when the margins are not included. However as soon as the two lines for the margins are uncommented, then the drop down content is much larger than it should be. Thoughts?

In addition, when the window is collapse as small as possible, rather than having just one drop-down element, "Home" and the drop-down bars are stacked. Why / how could I correct this?

NOTE: I source W3 CSS and hover-master

So for variables we have pages and the "sizes".

var pages = ["HOME","ABOUT","PAGE3","PAGE4","PAGE5","PAGE6","PAGE7","PAGE8"];
var extraSmall, small, medium, large;
extraSmall = 610;
small = 700;
medium = 800;
large = 1250;

For functions:

function getSizeInText(size) {

  if (size > large) {
    return("large")
  };
  if (extraSmall < size && size <  medium) {
    return("small")
  };
  if (medium <= size && size <= large) {
    return("medium")
  };
  if (size <= extraSmall) {
    return("extraSmall")
  }
}

function makeNavigation(navArray, navID, size) {

  var theID = document.getElementById(navID);
  var mar = 8;
  var pad = 2;
  theID.innerHTML = null;
  // theID.style.marginRight = mar + "%";
  // theID.style.marginLeft = mar + "%";
  theID.style.marginTop = mar/4 + "%";
  if (size == "extraSmall") {
    var numNav = navArray.length;
    theID.innerHTML += '<li class="w3-dropdown-hover w3-centered" '+
    'style="width:' + spaceAllocated + '%" >' +
    '<a class="hvr-reveal navFont">' +
    '<i class="fa fa-bars"></i></a>' +
    '<ul id="dropDownContent" class="w3-dropdown-content" style="width:'+ spaceAllocated +'%">' +
    '</ul>' + '</li>';
    for (var i = 0; i < numNav; i++ ) {
      document.getElementById('dropDownContent').innerHTML+=
      '<li style="width:' +
      (100 - 2*pad) + '%">'+
      '<a  class="hvr-reveal navFont" href="' + navArray[i].toLowerCase() + '.html">' +
      navArray[i] + '</a></li>';
    }
  }


  if (size == "small") {
    var numNav = navArray.length;
    var spaceAllocated = (100 ) / 2;
    for (var i = 0; i < 1; i++) {
        theID.innerHTML +=
        '<li style = "width:' +
        spaceAllocated +
        '%"><a  class="hvr-reveal navFont"' +
        ' href="' +
        navArray[i].toLowerCase() +
        '.html">' +
        navArray[i] + '</a></li>';
    };
    theID.innerHTML += '<li class="w3-dropdown-hover w3-centered" '+
    'style="width:' + spaceAllocated + '%" >' +
    '<a class="hvr-reveal navFont">' +
    '<i class="fa fa-bars"></i></a>' +
    '<ul id="dropDownContent" class="w3-dropdown-content" style="width:'+ spaceAllocated +'%">' +
    '</ul>' + '</li>';
    for (var i = 1; i < numNav; i++ ) {
      document.getElementById('dropDownContent').innerHTML+=
      '<li style="width:' +
      (100 - 2*pad) + '%">'+
      '<a  class="hvr-reveal navFont" href="' + navArray[i].toLowerCase() + '.html">' +
      navArray[i] + '</a></li>';
    }
  }

  if (size == "medium") {
    var numNav = navArray.length;
    var half = Math.floor(numNav/2);
    var spaceAllocated = (100 )  / (half+1);

    for (var i = 0; i < half; i++) {
        theID.innerHTML +=
        '<li style = "width:' +
        spaceAllocated +
        '%"><a  class="hvr-reveal navFont"' +
        ' href="' +
        navArray[i].toLowerCase() +
        '.html">' +
        navArray[i] + '</a></li>';
    };

    theID.innerHTML += '<li class="w3-dropdown-hover w3-centered" '+
    'style="width:' + spaceAllocated + '%" >' +
    '<a class="hvr-reveal navFont">' +
    '<i class="fa fa-bars"></i></a>' +
    '<ul id="dropDownContent" class="w3-dropdown-content" style="width:'+ spaceAllocated +'%">' +
    '</ul>' + '</li>';
    for (var i = half; i < numNav; i++ ) {
      document.getElementById('dropDownContent').innerHTML+=
      '<li style="width:' +
      (100 - 2*pad) + '%">'+
      '<a  class="hvr-reveal navFont" href="' + navArray[i].toLowerCase() + '.html">' +
      navArray[i] + '</a></li>';
    }
  };

  if (size == "large") {
    var numNav = navArray.length;
    var spaceAllocated = (100 )  / numNav;

    for (var i = 0; i < numNav; i++) {
        theID.innerHTML +=
        '<li style = "width:' +
        spaceAllocated +
        '%"><a  class="hvr-reveal navFont"' +
        ' href="' +
        navArray[i].toLowerCase() +
        '.html">' +
        navArray[i] + '</a></li>';
    };
  };
}

and then in the HTML:

<div class="w3-container w3-section"><ul id="navBar" class="w3-navbar w3-center"></ul></div>

<script type="text/javascript">
    var windowWidth;
    var size;

    jQuery(document).ready(function(){
      windowWidth = jQuery(window).width();
      size = getSizeInText(windowWidth);
      if (windowWidth > large) {}
      if (windowWidth <  medium) {}
      if (medium <= windowWidth && windowWidth <= large) {}
    });

    jQuery(window).resize(function () {
      windowWidth = jQuery(window).width();
      size = getSizeInText(windowWidth);
      if (windowWidth > large) {
        makeNavigation(pages, "navBar", size);
      }

      if (windowWidth <  medium) {
        makeNavigation(pages, "navBar", size);
      }

      if (medium <= windowWidth && windowWidth <= large) {
        makeNavigation(pages, "navBar", size);
      }



    });
  </script>

Update

programmer5000 gave a solution to this particular problem. However the same solution does not work when not using w3-css. How come?

/* Drop down content */
li a, .dropbtn {
    display: inline-block;
    text-align: center;
    text-decoration: none;
}

li.dropdown {
    display: inline-block;
}

.dropdown-content {
    display: none;
    position: absolute;
    text-align: center;
    width: inherit;
    z-index: 1;
}

.dropdown-content a {
    text-decoration: none;
    display: block;
}


.dropdown:hover .dropdown-content {
    display: block;
}




<nav id ='navigation-bar'>
  <ul>
    <li><a href="#"> HOME </a></li>    
    <li class="dropdown">
      <a class="dropbtn">TEST</a>
      <div class="dropdown-content">
        <a>1</a>
        <a>2</a>
        <a>3</a>
      </div>
    </li>
  </ul>
</nav>
SumNeuron
  • 4,850
  • 5
  • 39
  • 107
  • I don't see anything which could not be solved with CSS and HTML only. So may I ask why are you building this navigation with jQuery/javascript? Either way you didn't tag jQuery/javascript and have lots of jQuery/javascript. – caramba Feb 05 '17 at 17:09
  • @caramba I am new to web-dev and I couldn't figure out how to make the nav-bar resize when the window size changed without jQuery or some other listener... if you can show / teach me a simple way to do that with HTML, I am eager to learn – SumNeuron Feb 05 '17 at 17:20
  • What about css media queries ? – Ryan Holmes Feb 05 '17 at 17:26
  • I recommend looking into css media queries and breakpoints. https://www.youtube.com/watch?v=IUO1jltAzY8 – Donnie D'Amato Feb 05 '17 at 17:26
  • 2
    You should use [CSS media queries](https://developer.mozilla.org/de/docs/Web/CSS/Media_Queries/Using_media_queries) or [see a simple example on jsFiddle here](http://jsfiddle.net/DrSRT/) You should use HTML for your document and CSS for styling and when to use javascript you'll find out [here you-know-you-should-use-javascript-when](https://css-tricks.com/you-know-you-should-use-javascript-when/) – caramba Feb 05 '17 at 17:28
  • @Caramba can the media queries be continuous? e.g. always get the screen size and update on a gradient? Also, I used JS for setting up the nav-bar items and placing it on each web-page that I have, which I thought was good because of code reuse. Is that not the case? – SumNeuron Feb 05 '17 at 18:15
  • @SumNeuron yes they are continuous. So always from one step to the next step how ever you define in CSS. Reusing code is good but might not in this case. Also google got better with their robots and indexing but if javascript is turned off (which is often the case for robots) they will not find you navigation and can not index you page. so no content. – caramba Feb 05 '17 at 18:19
  • @SumNeuron the file in your github doesn't reflect the code you're referencing in the post. makeNavigation() isn't anywhere in the files. Can you please create a working demo of the project in your SO post? – Michael Coker Feb 06 '17 at 00:45
  • @MichaelCoker sorry, the code I uploaded to GitHub had some name changes since this was originally posted. e.g. `makeNavigation` is now `renderNavigationBar`. Either way the sentiment remains the same and the code on GitHub is heavily commented so it shouldn't be hard to work with – SumNeuron Feb 06 '17 at 04:48

1 Answers1

7

The bounty said:

2.) why when the window has minimum width, "HOME" is stacked on top of the drop-down bars.

Turns out it was a specificity issue. Try this:

@media screen and (max-width: 600px){
   .w3-navbar li:not(.w3-opennav) {
       width: 50% !important;
       float: left !important;
   }
}

That will solve that problem.

For #1:

1.) the differing widths from the main navigation bar elements and the drop down

#dropDownContent li {
    width: 100% !important;
}
.w3-dropdown-hover:hover .w3-dropdown-content{
    position: initial;
}

For both, it was just some weird absolute position thing and some specificity issues. Total: 12 lines of CSS!! Just paste this in a style tag at the end of the <head> and mention this question or me (programmer5000) in a comment.