City of Ghent Style Guide

Main menu

The main menu component helps users understand what the main sections of the website are, what the website is about and what they can find or do on the website.

When to use this component

Use the main menu component to offer one-click access to top tasks and/or the main sections of the website and to help users understand what the website is about and what they can find or do on the website.

A main menu is required for most websites.

When a menu menu is used, the main menu should be included:

  • On all pages of the website.
  • On all resolutions (desktop, tablet and mobile).

When not to use this component

Do not use the main menu component on:

  1. Websites that only have 1 main section. In this case, a main menu is not unnecessary and should not be used.
  2. Websites that have a lot of main sections and where the number of sections cannot be reduced even with an optimized information architecture. In this case a main menu is not the best choice. For this kind of websites, it’s better to rely on overview pages.

How it works

A main menu is composed as follows:

  1. A set of links to top tasks and/or the main sections of the website.
  2. The first item is a link to the front page of the website. In most cases, this is the page called the home page. This is shown using the label “Home”. In some special cases, when the front page is not a general home page, but has a more specific goal or specific content, the label can be something else than “Home”. However, this is an exception.
  3. Each item/link can be selected/active to show to website users on what page or in what main section of the website they are. Only one link at a time can be selected/active.

Javascript

This is a Javascript enabled molecule. Please check the javascript documentation on how to implement this correctly in your project.

{% set modalContent %}
  <div class="header">
    {% include '@logo' %}
  </div>
  {% if items and items.length > 0 %}
    <div class="menu-links">
      {% include '@list' with {
        type: 'links',
        items: items
      } %}
    </div>
  {% endif %}
  {{ auth }}
  {{ translate }}
{% endset %}

<nav class="menu">
  <button type="button"
          class="modal-trigger toggle"
          aria-expanded="false"
          aria-controls="{{ id }}">menu
  </button>
  {% if items and items.length > 0 %}
    {% include '@list' with {
      type: 'links',
      items: items
    } %}
  {% endif %}

  {% include "@modal" with {
    title_heading_level: 'span',
    id: id,
    classes: 'has-custom-binding menu',
    content: modalContent
  } %}
</nav>
<nav class="menu">
    <button type="button" class="modal-trigger toggle" aria-expanded="false" aria-controls="menu">menu
    </button>

    <ul class="">
        <li><a href="#" class="active">Home</a></li>
        <li><a href="#">Menu item 1</a></li>
        <li><a href="#">Menu item 2</a></li>
        <li><a href="https://www.google.com">Google</a></li>
    </ul>

    <div id="menu" class="modal has-custom-binding menu" role="dialog" aria-modal="true" tabindex="-1">

        <div class="modal-inner">
            <div class="modal-header">
                <button type="button" class="button close icon-cross modal-close" data-target="menu">
                    <span>Close</span>
                </button>
            </div>
            <div class="modal-content">
                <div class="header">
                    <a href="#" title="Home" class="site-logo " rel="home">

                    </a>
                </div>
                <div class="menu-links">

                    <ul class="">
                        <li><a href="#" class="active">Home</a></li>
                        <li><a href="#">Menu item 1</a></li>
                        <li><a href="#">Menu item 2</a></li>
                        <li><a href="https://www.google.com">Google</a></li>
                    </ul>

                </div>

            </div>
        </div>

        <div class="modal-overlay modal-close" data-target="menu" tabindex="-1"></div>
    </div>
</nav>
{
  "items": [
    "<a href=\"#\" class=\"active\">Home</a>",
    "<a href=\"#\">Menu item 1</a>",
    "<a href=\"#\">Menu item 2</a>",
    "<a href=\"https://www.google.com\">Google</a>"
  ],
  "id": "menu"
}
  • Content:
    nav.menu {
      margin: 0;
    
      button {
        @include button-icon;
        padding: 0;
        border: 0;
        background: transparent;
        font-size: .8rem;
    
        @include tablet {
          display: none;
        }
    
        &::before {
          order: 0;
          margin-right: .5rem;
          margin-left: 0;
        }
    
        &.toggle {
          @include icon(hamburger);
        }
    
        &.close {
          @include icon(cross);
        }
      }
    
      ul {
        @extend %list-no-style;
        @include tablet-and-below {
          display: none;
        }
    
        margin: 0;
    
        li {
          display: inline-block;
          margin-right: 1rem;
    
          a,
          a[href^="mailto:"],
          a[download],
          a[href^="http://"],
          a[href^="https://"] {
            @include reset-link-background;
            @include link-underlined;
    
            margin-bottom: 0;
            padding: .5rem 0;
          }
    
          a.active {
            @include bold-text;
          }
        }
      }
    }
    
    .modal.menu {
      @include tablet {
        display: none;
      }
    
      .modal-inner {
        .modal-header {
          position: absolute;
          right: 0;
          margin-top: 1rem;
          margin-right: .5rem;
          z-index: 7;
        }
      }
    
      .modal-content {
        flex: 1;
        padding: 0;
    
        .header {
          position: relative;
          margin: .6rem $gutter-width 1.6rem;
    
          &::before,
          &::after {
            @include theme('border-color', 'color-primary--lighten-4', 'header-border-bottom');
    
            position: absolute;
            top: 100%;
            width: 100%;
            height: 1rem;
            margin-top: .6rem;
            border-top: 2px solid;
            content: '';
          }
    
          &::before {
            left: -$gutter-width;
            width: 3rem + $gutter-width;
            border-right: 2px solid;
            border-top-right-radius: border-radius('radius-4');
          }
    
          &::after {
            right: -$gutter-width;
            // viewport - ::before + border-width + gutter-width
            width: calc(100% - 3rem + 2px + #{$gutter-width});
            border-left: 2px solid;
            border-top-left-radius: border-radius('radius-4');
          }
    
          button {
            position: absolute;
            right: 0;
            margin-top: .25rem;
          }
        }
    
        .menu-links {
          ul {
            @extend %list-no-style;
            margin: 0;
    
            li {
              @include tablet {
                display: inline-block;
                margin-right: 1rem;
              }
    
              margin-bottom: .8rem;
    
              &:first-child {
                margin-top: .8rem;
              }
    
              a,
              a[href^="mailto:"],
              a[download],
              a[href^="http://"],
              a[href^="https://"] {
                @include reset-link-background;
                @include link-underlined;
    
                padding: .5rem 0;
                line-height: 1.4rem;
              }
    
              a.active {
                @include bold-text;
              }
            }
          }
        }
    
        .authentication  {
          padding: 1.2rem 0;
    
          .content {
            padding: 0;
          }
        }
    
        .language-switcher {
          ul {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            margin: 0;
            padding: .6rem 0;
    
            li {
              padding: .6rem;
            }
          }
        }
    
        .authentication,
        .language-switcher {
          display: block;
        }
    
        .menu-links,
        .authentication,
        .language-switcher {
          margin: 0 1.2rem;
    
          &:not(:last-child) {
            @include theme('border-color', 'color-primary--lighten-4', 'mijn_gent-border-color');
            border-bottom: 2px solid;
          }
        }
      }
    }
    
  • URL: /components/raw/main-menu/_main-menu.scss
  • Filesystem Path: components/31-molecules/main-menu/_main-menu.scss
  • Size: 3.4 KB
  • Content:
    'use strict';
    
    (function () {
    
      if (!Modal) { // eslint-disable-line no-undef
        return;
      }
    
      const menu = document.querySelectorAll('.modal.menu');
    
      const createModal = function (modal) {
        // eslint-disable-next-line no-undef
        new Modal(modal, {
          // The modal is always visible from tablet and up,
          // this is atypical.
          resizeEvent: (open, close) => {
            if (window.innerWidth > 960) {
              close();
              modal.setAttribute('aria-hidden', 'false');
            }
            else {
              if (!modal.classList.contains('visible')) {
                modal.setAttribute('aria-hidden', 'true');
              }
            }
          }
        });
      };
    
      for (var i = menu.length; i--;) {
        createModal(menu[i]);
      }
    })();
    
  • URL: /components/raw/main-menu/menu.bindings.js
  • Filesystem Path: components/31-molecules/main-menu/menu.bindings.js
  • Size: 743 Bytes