Please rate this menu template

A bootstrap3 side bar. Is this a proper way to do it or is it too rudimentary?

The code does work.

{{ $currentPage := . }}
<!-- used to set active for a parent of a current page child item if they match -->
<!-- used to set active for a child item menu link if it matches with the current page -->
<!-- used to set active for a menu link if it matches with the current page -->

<div class="nav-side-menu">
  <!-- Toggle Button -->
  <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#menu-content">
  <span class="navbut"><i class="fa fa-bars fa-2x"></i></span></i>
  </button>
  <!-- Brand -->
  <div class="brand"><img src="{{ "infinity.gif" | relURL}}" alt="infinity" height="64" width="128" /></div>
  <!-- Respond to Toggle Button -->
  <div class="collapse navbar-collapse" id="menu-content">
    <ul>
      {{ range .Site.Menus.mainmenu }} <!-- loop through menu -->
      {{ if .HasChildren }}            <!-- if menu item has a child item, list names for each parent item -->
          <li data-toggle="collapse" class="collapsed {{ if $currentPage.HasMenuCurrent "mainmenu" . }}active{{ end }}" data-target="#{{.Name}}" aria-expanded="false" >
            <a>{{ .Name }}<i class="fas fa-chevron-down"></i></a>
          </li>
    <ul class="collapse sub-menu" id="{{.Name}}">
      {{ range .Children }}            <!-- loop through child items, list names foe each child item -->
        <li class="{{ if $currentPage.IsMenuCurrent "mainmenu" . }}active{{ end }}"><i class="fas fa-angle-right"></i><a href="{{.URL}}">{{.Name}}</a></li>
      {{end}}       <!-- end child loop -->
    </ul>
      {{else}}      <!-- if menu has no child items, list names for each item -->
        <li class="single {{ if $currentPage.IsMenuCurrent "mainmenu" . }}active{{ end }}"><a href="{{.URL}}">{{.Name}}</a></li>
    {{end}}         <!-- end checks for child items -->
    {{end}}         <!-- end menu loop -->
    </ul>
<!-- /Respond to Toggle Button -->
</div>
<!-- /nav-side-menu -->
</div>

What’s the purpose of the sidebar? How does it work on mobile? Does it add value to your users?

The purpose is well, it is me learning. Also almost every website has a top navigation, so i am trying to make it different. On mobile it becomes a hamburger button.

Thanks. Off-screen mobile menus can be hard to get right but they can be a nice experience when done right and are pretty natural for users used to mobile apps. The comments are helpful. Looks like you’re off to a good start.

Maybe consider adding some accessibility text or an ARIA role / attributes for aural user agents and Braille readers? The BS3 docs used to have an example layout for this with code.

Other than that a lot of these are CSS with a dash of JS but the general markup structure LGTM. If you want to avoid outputting empty menu wrappers you could use Scratch to check ahead if an if can’t cut it but that’s probably not worth the trouble if your expect the menu to always have items.

NullTx has a pretty groovy off-screen menu system if your looking for design inspiration. I can’t speak to its accessibility but it certainly is memorable.

that overlay menu does look interesting, will attempt to do something like that myself and report back here if i succeed

am not familiar with ARIA, will take a look

1 Like

After some “tinkering” and mostly searching online for tips and examples, I now have a menu template with two menus. One is a very much ordinary sidebar and the other, for smaller screens, is a collapsible overlay menu. It is “almost” as fancy as the one on the above mentioned page.
On xs screen side bar is not visible and a burger icon appears, top right. Clicking on burger icon calls JS which starts the overlay menu.

This is such since i had problems with same parent names used as “collapse id” in two different menus and i don’t know how to do it all in one.

Menus being sorted alphabetically, not sure how to apply weights to parent items (maybe in main config?), i created another menu and attached it bellow the first one, in the same template, which also changes the order (why there is a second loop).

menu template (one month duration): https://pastebin.com/q9HeWLw2

The rest is mostly CSS and a bit of JS.

edit: on line 25 there is one > too many

2 Likes

As it turns out, one can use JS to add and remove a class. Who knew. I did not.

Having two menus in a template is redundant. Will post final result once i stop changing things all the time.

Yep. Used to have to fight with string manipulation using element.style around the time jQuery came out. Now we have classList. Don’t forget to check your menu with JS disabled and no stylesheets! :sweat_smile:

I think that for now this is the final result (bellow).

Template is used to put together a collapsible menu, using bootstrap 3 (its css and js) along with required jquery, custom css and some custom java script.

On a large screen menu is a fixed collapsible sidebar with the brand image. On xs screens side bar moves out of the way and a burger icon appears top right, the brand image gets replaced by brand text. Clicking on the burger button activates custom java script which adds and removes classes to bring out or hide a full screen overlay menu.

Since menu order seems to be as followed: single items are put on top and parent items bellow, each ordered alphabetically (Bname of a single item is above Aname of a parent item) and weights seem to only affect child items. To get around this I have put a number in front of every parent name in front matter to customize the menu

menu:
  mainmenu:
    parent: 1PARENTNAME
    name: Child name
    weight: 2

and then used CSS

.nav-side-menu li::first-letter, .overlay li::first-letter {
  font-size: 0px !important;
}

which basically means i made the size of the first letter to be zero, so it is not seen, but still applied during menu sorting -1, 0, 1, 2 etc

Since single items are ordered above the parent items i made another menu and attached it to the bottom of the first one to list single items for which i want to be bellow parent items.

There is no ARIA and there is no tested solution for cases without JS and CSS (who does that anyway? TOR browser users?). Maybe ARIA will be considered at a later date.

The template:

{{ $currentPage := . }}
<!-- used to set active for a parent of a current page child item if they match -->
<!-- used to set active for a child item menu link if it matches with the current page -->
<!-- used to set active for a menu link if it matches with the current page -->

<!-- MENU -->
<div id="overlayOuter" class="nav-side-menu">
<!-- Brand Image -->
<div class="brand hidden-xs"><img src="{{ "img/infinity.gif" | relURL}}" alt="infinity" height="64" width="128" /></div>
<!-- X Close Overlay -->
<a href="javascript:void(0)" class="closebtn visible-xs" onclick="closeNav()"><span class="button-color"><i class="fas fa-times"></i></span></a>
<div id="overlayInner">
<ul>
{{ range .Site.Menus.mainmenu }} <!-- loop through menu -->
{{ if .HasChildren }}            <!-- if menu item has a child item, list names for each parent item -->
<li  data-toggle="collapse" class="collapsed {{ if $currentPage.HasMenuCurrent "mainmenu" . }}active{{ end }}" data-target="#{{.Name}}"><a>{{ .Name }}</a></li>
<ul class="sub-menu collapse" id="{{.Name}}">
{{ range .Children }}            <!-- loop through child items, list names foe each child item -->
<li class="{{ if $currentPage.IsMenuCurrent "mainmenu" . }}active{{ end }}"><i class="fas fa-angle-right"></i><a href="{{.URL}}">{{.Name}}</a></li>
{{end}}       <!-- end child loop -->
</ul>
{{else}}      <!-- if menu has no child items, list names for each item -->
<li class="single {{ if $currentPage.IsMenuCurrent "mainmenu" . }}active{{ end }}"><a href="{{.URL}}">{{.Name}}</a></li>
{{end}}       <!-- end checks for child items -->
{{end}}       <!-- end menu loop -->
{{ range .Site.Menus.bottom }}   <!-- second menu loop -->
<li class="single {{ if $currentPage.IsMenuCurrent "bottom" . }}active{{ end }}"><a href="{{.URL}}">{{.Name}}</a></li>
{{end}}       <!-- end second menu loop -->
</ul>
<div class="social">
<a href="" target="_blank"><i class="fab fa-facebook-square fa-2x"></i></a>
<a href="" target="_blank"><i class="fab fa-twitter-square fa-2x"></i></a>
<a href="" target="_blank"><i class="fab fa-linkedin fa-2x"></i></a>
<a href="" target="_blank"><i class="fab fa-instagram fa-2x"></i></a>
</div>
</div>
</div>
<!-- /MENU -->

<!-- Burger Open Overlay -->
<span class="button-color navbar-toggle" onclick="openNav()"><i class="fas fa-bars fa-2x"></i></span>
 <!-- Brand Text -->
<div class="brand-overlay visible-xs">E&ndash;pomoÄŤ</div>

menu thingy is not optimal solution and ie,edge and safari don’t seem to know what a negative number is, so only order with positive numbers…have not tried it in chrome. long live firefox

maybe also title="{{ .Name }}" should be added to <a>

1 Like