A Complicated Navigation Issue Solved with JS and CSS

- Resources, Tips, Tutorials, Lettering

The Premise:

In 2020, we needed a sub-navigation system on jtcc.edu that matched up to the HTML that an outside company had built for us and it turned out to be a bit more complex than you might expect. We needed it to automatically show the direct children of any page a visitor visits. However, if the page does not have children, we needed it to show the siblings of the current page. If the page has grandchildren, we did not want those to show and if the page has a parent, we did not want that to show.

What Made it Complex:

What made it complicated is the CMS we used, ExpressionEngine(EE) does not do this out-of-the-box. We used the Structure add-on to build the navigation on the site. However, it does not provide this specific functionality.

Example:

The below code would be output by EE/Structure but only the links within the span with the class of .children will show on the front-end of the site. In case you’re curious, the siblings spans are before and after the children span because the order they display is based on the order you have them in your Structure navigation for the entire site.

<ul>
  <span class="siblings">
    <li class="sub_nav_item">
      <a class="sub_nav_link not-current" href="/about/locations-tours/"
        ><span class="sub_nav_link_label">Locations</span
        ><span class="sub_nav_link_icon">
          <svg class="icon icon_caret_right">
            <use href="/images/icons.svg#caret_right"></use>
          </svg>
        </span>
      </a>
    </li>
  </span>
  <span class="children">
    <li class="sub_nav_item">
      <a
        class="sub_nav_link"
        href="/about/offices-and-divisions/institutional-effectiveness/"
        ><span class="sub_nav_link_label"
          >Office of Institutional Effectiveness</span
        ><span class="sub_nav_link_icon">
          <svg class="icon icon_caret_right">
            <use href="/images/icons.svg#caret_right"></use>
          </svg>
        </span>
      </a>
    </li>
    <li class="sub_nav_item">
      <a
        class="sub_nav_link"
        href="/about/offices-and-divisions/dean-of-students/"
        ><span class="sub_nav_link_label">Dean of Students Office</span
        ><span class="sub_nav_link_icon">
          <svg class="icon icon_caret_right">
            <use href="/images/icons.svg#caret_right"></use>
          </svg>
        </span>
      </a>
    </li>
  </span>
  <span class="siblings">
    <li class="sub_nav_item">
      <a
        class="sub_nav_link not-current"
        href="/about/employment-opportunities/"
        ><span class="sub_nav_link_label">Employment Opportunities</span
        ><span class="sub_nav_link_icon">
          <svg class="icon icon_caret_right">
            <use href="/images/icons.svg#caret_right"></use>
          </svg>
        </span>
      </a>
    </li>
  </span>
</ul>

The Solution

After many attempts to do it with EE and Structure code, I finally decided to get the back-end code to output everything(the entire navigation from the root of the site to the current page and all of it’s children) and use front-end code to get it to only show what we wanted.

CSS for Hiding Spans After

I used CSS to hide all the sibling links for a page if a page has children(.children ~ .siblings), all of the children links for a page if it has grand-children(.grand-children ~ .children), and lastly, all of the grand-children if a page has great grand-children(.great-grand-children ~ .grand-children).

.children ~ .siblings,
.grand-children ~ .children,
.great-grand-children ~ .grand-children{
   display:none;
}

The limit of CSS is that you can only affect elements after the current element you are calling. This is where JavaScript came in.

JavaScript(jQuery) for Hiding Spans Before

With a little bit of jQuery(which the site was already using in other places, so don’t come @ me JS Police!) I was able to hide all siblings if a page has grand-children and all siblings if a page has children.

<script>
   $(document).ready(function(){
    $(".grand-children").prevAll(".siblings").css({"display": "none"});
    $(".children").prevAll(".siblings").css({"display": "none"});
   });
</script>

Conclusion

I hope you found this helpful. If so, please share it so other developers can keep it in mind when building out their websites and navigation systems!

Please follow and like us:

April 18, 2022 by Jerad

Tagged: , , , ,

Reply or Comment

Your email address will not be published. Required fields are marked *


error

Enjoy this blog? Please spread the word :)