OffCanvas Menu is displayed only the first time

Hi there!

I have some trouble with something probably very basic. My skills in JS are not that great, so I might be missing something. A minimal pen for my problem : https://codepen.io/azzaare/pen/PoZXaJv

I have an off-canvas menu (for small size screen) with a hamburger button to open it. It works perfectly the first time. The html state at that moment is as follows (note that the offCanvas element has an empty style).

<div class="title-bar" data-responsive-toggle="offCanvas" *data-hide-for="medium" *="">
    <button class="menu-icon" type="button" data-toggle="offCanvas" aria-expanded="false" aria-controls="offCanvas"></button>
    <div class="title-bar-title">Menu</div>
</div>

<div class="off-canvas position-left reveal-for-medium is-transition-push is-closed" id="offCanvas" data-off-canvas="y8yw5d-off-canvas" aria-hidden="true" style="">
    <div class="top-bar">
        <button class="close-button" aria-label="Close menu" type="button" data-close="">
    <span aria-hidden="true">×</span>
        </button>
    </div>
</div>

Then, if we close the menu and reopen it, the offcanvas is blank (with style="display: none").

<div class="off-canvas position-left reveal-for-medium is-transition-push is-closed" id="offCanvas" data-off-canvas="y8yw5d-off-canvas" aria-hidden="true" style="display: none;">

I suppose I have to solve it with some JS, but I wonder why it is the default behavior. Anyway, what would the best way to handle it? Am I missing some basic option somewhere?

Sorry for the beginner question.

Hi again,

I still can’t solve my problem. As nobody answered here, I suppose my first explanation was not clear enough. Sorry for that.

Just to reformulate, I use an offCanvas item which cannot appear correctly more than once on mobile (small) display. I really have no idea of what is causing this problem. Help would be greatly appreciated.

I simplified my codepen, I hope it will help.

This seems to be an issue in combination with the responsive-toggle component setup.

Because this seems to work:

So far the combination of responsive toggle and offcanvas does not make much sense to me. Especially if there is no additional wrapper around the offcanvas component with an ID for the responsive toggle. Otherwise the responsive toggle component will confuse the offcanvas component by changing its visibility.

1 Like

Thank you so much!

It makes sense now that you point it out. It was probably a remnant of me toying with data-responsive-toggle when I started this project a few months ago…

I’m confused now.

I want:
on large screens a dropdown menu.
on small screens an accordion menu off-Canvas.
I can’t quite see how I can escape having a responsive+off-canvas menu

I have(roughly)

    button.button.hide-for-medium, data: toggle=onOffCanvas
    #onOffCanvas.offOcanvas.in-canvas-for-medium
        #mainMenu.topbar 
            .top-bar-left
                ul.vertical.medium-horizonta.menu data: responsive-menu= "accordion medium-dropdown"
                   li.menu_item
                   li.menu_item
                   li.menu_item
                       "Item"
                       ul.menu.vertical

You need 3 backticks to open and 3 backticks to close the code block (fenced code block).

Thanks. I’d overtyped the placeholder saying I could use markdown.

I’ll try again

<div class="address_bar" >
  <button class="button hide-for-medium" type="button" data-toggle="onOffCanvas" aria-expanded="false"  aria-controls="onOffCanvas" >
  </button >
  <div ><a >Address Bar Item 1</a ></div >
  <div ><a >Address Bar Item 2</a ></div >
  <div ><a >Address Bar Item 3</a ></div >
</div >
<div id="onOffCanvas" class="off-canvas position-left in-canvas-for-medium" data-options="inCanvasFor:medium;" >

  <div class="top-bar" id="mainMenu" >
    <div class="top-bar-left" >
      <ul class="vertical medium-horizontal menu" data-responsive-menu="accordion medium-dropdown" >
        <li class="menu_item" ><a href="url">Title</a ></li >
        <li class="menu_item" ><a href="/" >Title</a >
          <ul id="650" class="menu vertical" >
            <li class="menu_item" ><a href="url" >Title</a ></li >
            <li class="menu_item" ><a href="url" >Title</a ></li >
          </ul >
        </li >
        <li class="menu_item" ><a href="url" >Services</a >
          <ul id="793" class="menu vertical" >
            <li class="menu_item" ><a href="url" >Title</a ></li >
          ... ... ...
          </ul >
        </li >
      </ul >
    </div >
    <div class="top-bar-right" >
     etc etc
    </div >
  </div >

  <button class="close-button" aria-label="Close menu" type="button" data-close >
    <span aria-hidden="true" >&times;</span >
  </button >
</div >

Above is my markup for an onCanvas/offCanvas menu. This is what I had expected…

On a small screen the Address Bar at the top contains the menu toggle and a couple of icons.
When the menu toggle is clicked the off-canvas menu slides in and presents the vertical menus.
Where there is a submenu it acts as an accordion, pushing lower menu items down. It will be indented.

On a large screen the address bar hides the menu toggle, and spreads its icons (and text) across the width of the screen.
Below that a horizontal menu appears showing only the top level items in a top-bar-left and top-bar-right.

Where there is a submenu, there is a downarrow indicator. When hovered the submenu appears below the main menu, overlaying the page content.

At least that is my intention.

Much of it does happen, but it seems to depend on what initializations I run. I don’t see the switch between accordion/dropdown. [^2]

Calling $(document).foundation() doesn’t seem to handle the menus.
[^1]

If I initialize the MainMenu (or its children) as DropdownMenus, they acquire the class opens-right, rather than appearing below the menu.

If I add

    new ResponsiveMenu($(mainMenu), {
      hideFor: 'medium',
      animate: true
    })

submenus are ignored and appear on screen in full.

I can additionally initialize mainMenu as an accordion menu - which achieves the result I want on a small screen, but still presents an accordion menu on the wide screen.

I have even tried initializing MainMenu three times with Responsive/Accordion/Dropdown - although I haven’t exhaused the combinatorial possibilites this offers. The results, btw, were fair but favoured either dropdown or accordion, but not both.

I guess my real question is about the js initialization. To get an offCanvas/onCanvas, responsive accordion/dropdown menu, what do I need to do?

Many thanks

Anita

[^1]: Any thoughts of removing the dependency on jquery?

[^2]: I’ve been through many iterations of the markup for this, and I have seen dropdowns/accordions working. Currently the on/off Canvas is looking good, but the submenus are not.

[^3]: Oh, I’ve just about finished, and now I’ve discovered where the viewable copy is. Right under the yellow note.

More extra thanks. :sunny:

We will drop that in Foundation Sites 7. So far the whole framework requires jQuery and it is not easy to change the whole code to run without jQuery.

Hi,

I seem to have cracked this particular nut. Writing it all out, and isolating it into a pen helped.

In the end I have

  1. A title-bar, including a toggle button for onOffCanvas in addition to some always visible elements.
  2. An off-canvas section (on-canvas for medium), which contains
    2.1 A top-bar (split into left and right)
    2.1.1 Each section (left and right) is a responsive menu which is an accordion on small screens and dropdown on large screens.

Classes

  1. Within the menus, all items which have a submenu have a class of has-submenu.
  2. All submenus have a class of submenu.

Reading the doc for menus, responsive menus, dropdown menus etc, this wasn’t obvious to me.

Initialization

  • Top-bar-left and top-bar-right are initialized as separate responsive menus.
    Although the top-bar item could be initialized as a single responsive menu, incorporating the left and right sides, the drop-down positioning was not what I expected.
  • Finally the offCanvas element is initialized.

As ever, thank you.