Jekyll One

Fulltext Search

MMenu, short for Mobile Menu, is a JavaScript plugin for creating an app look-alike off-canvas (sidebar) menu fully integrated with J1 Template. The plugin turns a basic HTML menu structure into a fully functional sidebar menu with sliding submenus.

In the J1 Template, MMenu is the engine behind all mobile menus and drawers: the main navigation on small screens, the table of contents (TOC) drawer, and the optional sidebar drawer. You do not need to write any JavaScript to use these menus. All menus are created automatically by the J1 Navigator module and are configured by simple settings in a YAML configuration file.

J1 Template use the free variant MMenu Light of version v3.1.1.

10-30 Minutes to read

Getting started

The plugin MMenu knows its way around a bit more complex HTML structures as well, so you probably don’t need to change any markup if you’re migrating from another script or plugin. All the plugin needs is a simple HTML list structure built from <ul />, <li /> and <a /> (or <span />) elements.

After the plugin is invoked, there are two add-ons available for the menu: navigation and offcanvas.

navigation()

Creates the navigation with a fixed navbar and sliding submenus from <nav />, <ul />, <li /> and <a /> (or <span />) elements. Submenus slide in from the right when a parent item is tapped, and a back button in the navbar brings the user back to the parent panel.

offcanvas()

Creates an off-canvas drawer. This drawer can be populated with any kind of content. A drawer slides in from the left or right side of the screen and closes when the user taps the darkened area (the backdrop) next to it.

Both add-ons navigation and offcanvas have their own set of options, CSS variables and API methods. You can find all of them in the sections Options, Styling (CSS) and API of this manual.

How MMenu is used in J1 Template

Good news first: you do not need to write any JavaScript code to use mobile menus in the J1 Template. The template ships with a ready-to-use integration, and all menus are configured by simple settings in a YAML configuration file.

The integration consists of three building blocks:

The J1 adapter (mmenu.js)

A small piece of JavaScript, called an adapter, that connects the MMenu Light plugin with the J1 Template. The adapter reads your YAML settings, loads the menu content, and creates all configured menu instances automatically when a page is loaded.

The YAML configuration (navigator.yml)

All mobile menus are part of the J1 Navigator module. Their settings live in the file _data/modules/navigator.yml under the key nav_mmenu. Here you enable or disable menus, set the drawer position, the menu title, the color theme, and more.

The HTML data files

The content of each menu (the link structure) is not part of the page itself. It is stored in separate HTML data files, for example /assets/data/mmenu/index.html for the main navigation. The adapter loads these files in the background (via AJAX) when a page is opened.

Menu types

The J1 integration knows two types of mobile menus. The type is set for each menu instance by the config key content.type:

navigation

A full mobile navigation menu with sliding submenus. The J1 Template uses this type for the main site navigation on small screens. It is opened and closed by the hamburger button in the navigation bar.

drawer

A simple content drawer without submenus. The J1 Template uses this type for the table of contents (TOC) drawer and the optional sidebar drawer. A drawer can hold any HTML content, for example the TOC of the current page or info boxes about the site.

Using the plugin standalone

If you want to use MMenu Light outside of the J1 integration, for example on a custom page, the plugin can be invoked manually with a few lines of JavaScript:

<script>
    document.addEventListener(
      "DOMContentLoaded", () => {
        const menu = new MmenuLight(
            document.querySelector( "#my-menu" ),
            "(max-width: 600px)"
        );
        const navigator = menu.navigation({
            // options
        });
        const drawer = menu.offcanvas({
            // options
        });
      }
    );
</script>

The first argument passed to MmenuLight is the HTML element that should be turned into a mobile menu. The second argument is a media query string: the menu is only active as long as the media query matches, for example on screens with a width of 600 pixels or less.

Options

The mmenu light plugin and both the navigation and offcanvas add-ons provide a set of options for customizing your menu. An option is a simple key/value pair. The default values can be overridden by passing new values to the plugin or to the add-on methods.

In the J1 Template, you normally do not pass these options in JavaScript yourself. Instead, you set them in the YAML configuration file navigator.yml, and the J1 adapter passes them to the plugin for you. See the section J1 YAML configuration below for all available settings.

<script>
    document.addEventListener(
      "DOMContentLoaded", () => {
        const menu = new MmenuLight(
            document.querySelector( "#my-menu" ),
            "(max-width: 600px)"
        );
        const navigator = menu.navigation({
            // options
        });
        const drawer = menu.offcanvas({
            // options
        });
      }
    );
</script>

MMenu Plugin

The plugin itself accepts two options. Both are passed when a new MmenuLight instance is created.

Table 1. Options for the plugin
Option Datatype Default Description

node

HTMLElement

null

The HTML element you want to turn into an off-canvas menu. .Example

<script>
  const menu = new MmenuLight(
    document.querySelector( "#my-menu" ),
    "(max-width: 600px)"
  );
</script>

mediaQuery

String

all

MediaQuery for when the menu should be enabled. The default value all means the menu is always active, on all screen sizes. The J1 Template uses this default and controls the visibility of the menus by its own responsive settings.

Navigation add-on

The navigation add-on turns the HTML list structure into a navigation menu with a fixed navbar and sliding submenus.

Table 2. Options for the navigation add-on
Option Datatype Default Description

selected

String

"Selected"

Classname to use for finding the selected <li />. The menu item that carries this CSS class is marked as the currently active page. .Example

<script>
  const navigator = menu.navigation ({
    // navigator options
    selected:         "Selected",
    slidingSubmenus:  true,
    title:            "My Menu",
    theme:            "dark"
  });
</script>

slidingSubmenus

Boolean

true

Whether or not to use sliding submenus (forced to be false in IE11). If enabled, submenus slide in from the right as separate panels. If disabled, submenus expand and collapse vertically below their parent item.

title

String

"Menu"

The title above the main panel. For subpanels the text in its parent menu item is used.

theme

String

"light"

Color scheme to use. Possible values: "light" or "dark". The J1 Template uses the dark theme by default.

Offcanvas add-on

The offcanvas add-on places the menu in a drawer that slides in from the side of the screen.

Table 3. Options for the offcanvas add-on
Option Datatype Default Description

position

String

"left"

The position for the menu. Possible values: "left" or "right". The drawer slides in from the given side of the screen. .Example

<script>
  const drawer = menu.offcanvas ({
    // drawer options
    position:         "left"
  });
</script>

J1 YAML configuration

In the J1 Template, all mobile menu settings are part of the Navigator module. The configuration is split into two files:

Default settings

_data/modules/defaults/navigator.yml — the factory defaults shipped with the template. Do not change this file; it documents all available options and their default values.

User settings

_data/modules/navigator.yml — your personal settings. Every value you set here overrides the corresponding default value.

All mobile menu settings live under the key nav_mmenu.

Default settings (plugin and add-ons)

The default settings map directly to the plugin and add-on options described above. They apply to all menu instances.

nav_mmenu:
  enabled:                            false
  nav_main_menu:                      navigator_nav_menu
  nav_quicklinks:                     quicklinks
  mmenu_plugin:
    node:                             "null"
    mediaQuery:                       all
    max_width:                        100000
  mmenu_navigator:
    selected:                         Selected
    slidingSubmenus:                  true
    title:                            Navigation
    theme:                            dark
  mmenu_drawer:
    position:                         right
Table 4. Default settings for the key nav_mmenu
Setting Datatype Default Description

enabled

Boolean

false

Enables or disables the mobile menus of the Navigator module as a whole. Set this key to true in your user settings to activate the mobile menus.

nav_main_menu

String

navigator_nav_menu

The id of the (desktop) main menu container. Used by the adapter to toggle the visibility of the main menu while a drawer is open.

nav_quicklinks

String

quicklinks

The id of the quicklinks container. Used by the adapter to hide the quicklinks while the mobile navigation is open and to show them again when the menu is closed.

mmenu_plugin.node

String

"null"

Maps to the plugin option node. The value "null" lets the adapter select the menu element by the configured container id.

mmenu_plugin.mediaQuery

String

all

Maps to the plugin option mediaQuery.

mmenu_plugin.max_width

Number

100000

Maximum screen width (in pixels) for which the menus are created. The very large default value practically means no limit. The adapter builds the media query string (max-width: <value>px) from this setting.

mmenu_navigator.selected

String

Selected

Maps to the navigation add-on option selected.

mmenu_navigator.slidingSubmenus

Boolean

true

Maps to the navigation add-on option slidingSubmenus.

mmenu_navigator.title

String

Navigation

Maps to the navigation add-on option title. The title shown above the main panel of the mobile navigation.

mmenu_navigator.theme

String

dark

Maps to the navigation add-on option theme.

mmenu_drawer.position

String

right

Maps to the offcanvas add-on option position. The default position for all drawers; can be overridden per menu instance.

Instance settings (menus)

Each mobile menu is configured as one entry in the list menus of your user settings. The J1 Template ships with three preconfigured instances: the main navigation, the TOC drawer, and the (disabled) sidebar drawer.

nav_mmenu:
  enabled:                          true
  menus:
    # NAVIGATION Main
    - menu:
        enabled:                    true
        xhr_container_id:           navigator_nav_mmenu
        xhr_data_element:           menu_mmenu
        xhr_data_path:              /assets/data/mmenu/index.html
        drawer:
          position:                 right
        content:
          id:                       menu_mmenu
          type:                     navigation
          title:                    Navigation
          theme:                    dark
          button:                   "#mmenu-button"
          button_activated:         always
    # DRAWER TOC
    - menu:
        enabled:                    true
        xhr_container_id:           navigator_toc_mmenu
        xhr_data_element:           toc_mmenu
        xhr_data_path:              /assets/data/mmenu_toc/index.html
        drawer:
          position:                 right
        content:
          id:                       toc_mmenu
          type:                     drawer
          title:                    Table of Contents
          theme:                    dark
          button:                   "#open_mmenu_toc"
          button_activated:         "js-toc-content"
Table 5. Instance settings for a single menu
Setting Datatype Default Description

enabled

Boolean

false

Enables or disables this menu instance.

xhr_container_id

String

none

The id of the (empty) container element on the page into which the menu content is loaded via AJAX.

xhr_data_element

String

none

The id of the element inside the HTML data file that contains the menu content to be extracted.

xhr_data_path

String

none

The path to the HTML data file that provides the menu content, for example /assets/data/mmenu/index.html.

drawer.position

String

right

The side of the screen from which this drawer slides in. Possible values: left or right. Overrides the default set by mmenu_drawer.position.

content.id

String

none

The id of the top element of the menu content, for example the <ul /> of the navigation or the <div /> of a drawer. The adapter makes this element visible after the menu has been initialized.

content.type

String

none

The type of the menu instance. Possible values: navigation (mobile navigation with sliding submenus) or drawer (content drawer).

content.title

String

none

The title of the menu shown in the navbar of the panel.

content.theme

String

dark

Color scheme for the menu. Possible values: light or dark.

content.button

String

none

A CSS selector for the button (or element) that opens this menu, for example "#mmenu-button" for the hamburger button of the navigation bar or "#open_mmenu_toc" for the TOC button.

content.button_activated

String

always

Controls when the open button is active. The value always means the button always opens the menu. Any other value is treated as a CSS classname: the button only works if the <main /> element of the current page carries this class. Example: the TOC drawer uses js-toc-content, so the TOC button only opens the drawer on pages that actually provide a table of contents.

Styling (CSS)

It’s pretty easy to change the styling for the mmenu light plugin: just override some of the CSS values and variables. A CSS variable (also called a custom property) is a named value, like --mm-ocd-width, that is used at several places inside the plugin styles. If you change the variable, all styles that use it change automatically.

  .mm {
      background: #ffe;
      color: #330;
      --mm-spn-item-height: 46px;
      --mm-ocd-max-width: 500px;
  }

In the J1 Template, the base styles of the plugin are provided by the file mmenu-light.css, and the J1 theme styles (colors, fonts and responsive behavior) are provided by the file mmenu.css of the Uno theme. If you want to change the look of the mobile menus, add your overrides to the theme file rather than editing the base styles.

Navigation add-on

The navigation panels use the CSS class prefix mm-spn (sliding panel navigation). Colors are set by simple CSS values, sizes by CSS variables.

Table 6. Values
Value Datatype Default Description

background-color

Color

#f3f3f3

Background-color for the menu. The default value applies to the light theme; the dark theme uses a dark background. The J1 Uno theme sets the background of the dark theme to black (#000).

color

Color

#444

Color for the text and borders in the menu. The default value applies to the light theme; the J1 Uno theme sets the text color of the dark theme to a light gray (#e3e3e3).

Table 7. Styles (see mmenu-light.css)
Variables Datatype Default Description

--mm-spn-item-height

CSS value

50px

Height for menu items.

--mm-spn-item-indent

CSS value

20px

Indent for menu items.

--mm-spn-line-height

CSS value

24px

Line-height for text in the menu.

  :root {
    --mm-spn-item-height: 50px;
    --mm-spn-item-indent: 20px;
    --mm-spn-line-height: 24px
  }
  .mm-spn ul:after {
    content: '';
    display: block;
    height: 50px;
    height: var(--mm-spn-item-height)
  }
  .mm-spn li:before {
    content: '';
    display: block;
    position: absolute;
    top: 25px;
    top: calc(var(--mm-spn-item-height)/ 2);
    right: 25px;
    right: calc(var(--mm-spn-item-height)/ 2);
    z-index: 0;
    ...
  }
  .mm-spn a,
  .mm-spn span {
    position: relative;
    z-index: 1;
    padding: 13px 20px;
    padding: calc(
      (var(--mm-spn-item-height)
      - var(--mm-spn-line-height))/ 2)
      var(--mm-spn-item-indent)
  }
  .mm-spn a:not(:last-child) {
    width: calc(100% - 50px);
    width: calc(100% -
      var(--mm-spn-item-height))
  }
  .mm-spn.mm-spn--navbar:before {
    content: '';
    display: block;
    position: absolute;
    top: 25px;
    top: calc(var(--mm-spn-item-height)/ 2);
    left: 20px;
    left: var(--mm-spn-item-indent);
    width: 10px;
    ...
  }
  .mm-spn.mm-spn--navbar:after {
    content: attr(data-mm-spn-title);
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 50px;
    height: var(--mm-spn-item-height);
    padding: 0 40px;
    padding: 0 calc(var(--mm-spn-item-indent) * 2);
    line-height: 50px;
    line-height: var(--mm-spn-item-height);
    ...
  }
  .mm-spn.mm-spn--navbar ul {
    top: 51px;
    top: calc(var(--mm-spn-item-height) + 1px)
  }
  .mm-spn.mm-spn--vertical ul ul:after {
    height: 25px;
    height: calc(var(--mm-spn-item-height)/ 2)
  }

Offcanvas add-on

The off-canvas drawer uses the CSS class prefix mm-ocd (off-canvas drawer). Its position and size are controlled by CSS values and variables.

Table 8. Values
Value Datatype Default Description

top

CSS value

0

Position relative to the top of the page. The J1 Uno theme sets the value to 48px on small screens (below 992px) to create an offset for the navigation bar, so the drawer opens below the navbar.

bottom

CSS value

0

Position relative to the bottom of the page.

Table 9. Styles (see: mmenu-light.css)
Variables Datatype Default Description

--mm-ocd-width

CSS value

80%

Width for the menu.

--mm-ocd-min-width

CSS value

200px

Minimal width for the menu.

--mm-ocd-max-width

CSS value

440px

Maximum width for the menu.

  :root {
    --mm-ocd-width: 80%;
    --mm-ocd-min-width: 200px;
    --mm-ocd-max-width: 440px
  }
  .mm-ocd__content {
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 2;
    width: 80%;
    width: var(--mm-ocd-width);
    min-width: 200px;
    min-width: var(--mm-ocd-min-width);
    max-width: 440px;
    max-width: var(--mm-ocd-max-width);
    background: #fff;
    ...
  }
  .mm-ocd__backdrop {
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 3;
    width: calc(100% - 80%);
    width: calc(100% - var(--mm-ocd-width));
    min-width: calc(100% - 440px);
    min-width: calc(100% - var(--mm-ocd-max-width));
    max-width: calc(100% - 200px);
    max-width: calc(100% - var(--mm-ocd-min-width));
    background: rgba(3, 2, 1, 0)
  }

J1 theme customizations

The J1 Uno theme file mmenu.css adds a set of overrides to adapt the plugin styles to the look of the template. The most important ones are:

Dark drawer colors

The drawer content (.mm-ocd__content) and the navigation panels (.mm-spn—​dark) use a black background and light gray text to match the dark J1 mobile navigation.

Menu title

The menu title in the navbar is aligned to the left and shown in a larger font size (x-large).

Hover highlighting

Menu items are highlighted with a dark gray background (#424242) when the user moves the pointer over them.

Navbar offset

On small screens (below 992px), the drawer gets a top offset of 48px, so it opens below the fixed navigation bar of the template.

Sidebar widgets

The class mm-side and its child classes (widget, heading, link) style the content boxes of the sidebar and TOC drawers.

API

After invoking the add-ons, an API is available for each add-on. With this API, you can invoke the add-on methods to control the plugin manually, for example to open a drawer when a button is clicked.

<script>
  document.addEventListener(
    "DOMContentLoaded", () => {
      const menu = new MmenuLight(
          document.querySelector( "#my-menu" )
      );
      const navigator = menu.navigation();
      const drawer = menu.offcanvas();
      navigator.openPanel(
        document.querySelector( "#my-ul" )
      );
      document.querySelector( 'a[href="#my-menu"]' )
      .addEventListener( 'click', ( evnt ) => {
          evnt.preventDefault();
          drawer.open();
      });
    }
  );
</script>

Navigation add-on

The API of the navigation add-on provides one method to control the panels of the menu.

openPanel

Invoke this method to open a panel in the menu. A panel is one level of the menu, technically a <ul /> element. Opening a panel of a submenu slides that submenu into view.

Table 10. Arguments
Arguments Datatype Default Description

panel

HTMLElement

null

Panel (UL) to open.

Off-Canvas add-on

Creates an off-canvas drawer. This drawer can be populated with any kind of content. The API of the offcanvas add-on provides two methods to open and close the drawer.

Table 11. Methods for the offcanvas add-on
Method Datatype Default Description

open

NA

NA

Invoke this method to open the menu.

Example
<script>
  const drawer = menu.offcanvas ({
    // drawer options
    position:         "left"
  });
  _open_menu.addEventListener( "click", function (e) {
    e.preventDefault();
    drawer.open();
  });
</script>

close

NA

NA

Invoke this method to close the menu.

Example
<script>
  const drawer = menu.offcanvas ({
    // drawer options
    position:         "left"
  });
  _close_menu.addEventListener( "click", function (e) {
    e.preventDefault();
    drawer.close();
  });
</script>

J1 adapter API

The J1 adapter j1.adapter.mmenu wraps the plugin API and manages all configured menu instances for you. Normally you do not call the adapter methods yourself; they are invoked automatically by the J1 core at page load. The methods are documented here for completeness and for troubleshooting.

Table 12. Methods of the adapter j1.adapter.mmenu
Method Arguments Returns Description

init

options (Object)

NA

The adapter initializer. Reads the module options from the YAML configuration, waits until the J1 core has finished and the page content is visible, and then starts the menu loader mmenuLoader.

mmenuLoader

mmOptions (Object)

NA

Loads the HTML content of all enabled menu instances from their configured HTML data files (xhr_data_path) into the page containers (xhr_container_id) via AJAX. When the data is loaded, the method starts the menu initializer mmenuInitializer.

mmenuInitializer

mmOptions (Object)

NA

Creates an MmenuLight instance for every enabled menu configured in the YAML settings. Depending on the config key content.type, the instance is created as a navigation menu (with the navigation and offcanvas add-ons) or as a content drawer (offcanvas add-on only). The method also connects the configured open button (content.button), respects the setting content.button_activated, and hides or shows the quicklinks menu when a menu is opened or closed.

messageHandler

sender (String), message (Object)

Boolean

Receives and processes messages sent by other J1 modules, for example the notification module_initialized.

setState

stat (String)

NA

Sets the current processing state of the module. Used states are: not_started, started, loading and finished.

getState

NA

String

Returns the current processing state of the module.

You can check the state of the mobile menu module at any time from the browser console by calling j1.adapter.mmenu.getState(). If the state is finished, all configured menus have been created successfully.