Implementing smart drop-down menus

Caution

This is an advanced tutorial and is not supported by Shopify. Knowledge of web design languages such as HTML, CSS, Javascript and Liquid is required. We suggest hiring a Shopify Expert if you are not comfortable proceeding with the following tutorial.

Note

This is an article for theme designers.

Before reading further...

Before you add any drop down menus, take a look at these articles and see whether your layout adheres to proper web design standards:

Designing Drop-Down Menus: Examples and Best Practices (Smashing Magazine) Son of Suckerfish Dropdowns (HTML Dog)

What Shopify gives us out the box

  • With Shopify, you can create new lists of links and add them to our shop.

  • you create a menu (list of links) under the Navigation tab, then you add a bit of code to our theme to show that menu.

What Shopify does not give us

  • Shopify does not offer the possibility to nest a menu inside a menu under the Navigation tab. menus have 1 level only. There are no multiple-level menus in Shopify.

Using a naming convention to create sub-menus

So, there's no way to create sub-menus in Shopify under the Navigation tab. Should that stop us from creating a multi-level menu? Certainly not. With a bit of logic added to our theme, and a smart naming convention applied to the name of our menus under the Navigation tab, you, as a designer, will be able to create a dynamic multi-level menu in Shopify — 'dynamic' as in not hard-coded in the theme.

How would that naming convention work?

For every link you wish to connect to a sub-menu, you'll create a menu that will have the same name as said (parent) link. Say what? Let's take an example. A typical Main Menu in Shopify contains the following links:

Add smart drop 1

Say you wanted to include a link called Shop by Brand:

Add smart drop 2

And you wanted that link to become a drop-down sub-menu listing the brands in our shop, with links to vendor collections. Then what you'd do is create a menu called Shop by Brand:

Add smart drop 3

Name it, and populate the list with links you want to drop down from the Shop by Brand main menu button.

Add smart drop 4

Note

To turn any link of your Main Menu into a 'parent' link, create a 'child' menu for it using the name of your parent link.

Now, time to make your theme smart.

Editing the HTML / Liquid that outputs your Main Menu

There are many solutions out there to create fancy drop-down menus.

The HTML markup these solutions rely on is always the same:

<ul id="nav">
    <li><a href="#" >Link 1</a></li>
    <li><a href="#" >Link 2</a>
        <ul>
            <li><a href="#" >Link3</a></li>
            <li><a href="#" >Link4</a></li>
        </ul>
    </li>
    <li><a href="#" >Link 5</a></li>
</ul>

Let's make it happen. In your shop admin, Go to the Edit HTML/CSS page.. On the Edit HTML/CSS page, locate the file theme.liquid under Layouts. Click on theme.liquid to open the file in the online code editor.

You will need to locate the Liquid / HTML that outputs your Main Menu. Look for the handle of the menu, it's main-menu. In the Reconfigured theme, the HTML / Liquid for the main menu is:

<ul class="navigation">{% for link in linklists.main-menu.links %}{% assign current = false %}{% if template == 'index' and link.url == '/' %}{% assign current = true %}{% elsif collection.url == link.url %}{% assign current = true %}{% elsif blog.url == link.url %}{% assign current = true %}{% elsif page.url == link.url %}{% assign current = true %}{% elsif page_title == link.title %}{% assign current = true %}{% elsif template == 'list-collections' and link.url == '/collections' %}{% assign current = true %}{% elsif page_title == 'Products' and link.url == '/collections/all' %}{% assign current = true %}{% elsif template == 'article' and link.url == article.url %}{% assign current = true %}{% endif %}
  <li{% if forloop.first %} class="first"{% endif %}><a{% if current %} class="active"{% endif %} href="{{ link.url }}">{{ link.title }}</a></li>{% endfor %}
</ul>

There is a fairly long segment of Liquid that determines if either of the menu items points to the current page, i.e. is an 'active link'. When it does, it adds an 'active' class to said item. Let's add a few line breaks to see the relevant code more clearly:

<ul class="navigation">

{% for link in linklists.main-menu.links %}

<!-- does this link in our iteration point to the current page? -->
{% assign current = false %}{% if template == 'index' and link.url == '/' %}{% assign current = true %}{% elsif collection.url == link.url %}{% assign current = true %}{% elsif blog.url == link.url %}{% assign current = true %}{% elsif page.url == link.url %}{% assign current = true %}{% elsif page_title == link.title %}{% assign current = true %}{% elsif template == 'list-collections' and link.url == '/collections' %}{% assign current = true %}{% elsif page_title == 'Products' and link.url == '/collections/all' %}{% assign current = true %}{% elsif template == 'article' and link.url == article.url %}{% assign current = true %}{% endif %}
<!-- end of soul-searching about active class -->

  <li{% if forloop.first %} class="first"{% endif %}><a{% if current %} class="active"{% endif %} href="{{ link.url }}">{{ link.title }}</a></li>

{% endfor %}

</ul>

For each link in our Main Menu, we need to check if there is a menu defined that bears the same name, and if that menu contains any link. Reformatted to be easy on the eye, we get this:

<ul class="navigation">

  {% for link in linklists.main-menu.links %}

<!-- does this link in our iteration point to the current page? -->
{% assign current = false %}{% if template == 'index' and link.url == '/' %}{% assign current = true %}{% elsif collection.url == link.url %}{% assign current = true %}{% elsif blog.url == link.url %}{% assign current = true %}{% elsif page.url == link.url %}{% assign current = true %}{% elsif page_title == link.title %}{% assign current = true %}{% elsif template == 'list-collections' and link.url == '/collections' %}{% assign current = true %}{% elsif page_title == 'Products' and link.url == '/collections/all' %}{% assign current = true %}{% elsif template == 'article' and link.url == article.url %}{% assign current = true %}{% endif %}
<!-- end of soul-searching about active class -->

  <li{% if forloop.first %} class="first"{% endif %}>
    <a{% if current %} class="active"{% endif %} href="{{ link.url }}">{{ link.title }}</a>
    {% capture child_list_handle %}{{ link.title | handle }}{% endcapture %}
    {% if linklists[child_list_handle] and linklists[child_list_handle].links.size > 0 %}
    <ul>
      {% for l in linklists[child_list_handle].links %}
      <li><a href="{{ l.url }}">{{ l.title }}</a></li>
      {% endfor %}
    </ul>
    {% endif %}
  </li>

  {% endfor %}

</ul>

Brace yourself as the results of this edit will probably be visually disappointing to you.

Add smart drop 5

The menu is begging for some styling through CSS.

Using the Superfish plugin (jQuery)

Downloading Superfish

Download the Superfish massage therapist here: http://users.tpg.com.au/j_birch/plugins/superfish/#download

Unzip the file.

Uploading the script files to your theme assets

On the Edit HTML/CSS page, under Theme Assets, click on the Upload a new theme asset link. Browse to the following files and upload:

  • hoverIntent.js

  • jquery.bgiframe.min.js

  • superfish.js

  • supersubs.js

Including these script files

In the head element of our theme.liquid layout file, we will include the script files:

{{ 'hoverIntent.js' | asset_url | script_tag }}
{{ 'jquery.bgiframe.min.js' | asset_url | script_tag }}
{{ 'superfish.js' | asset_url | script_tag }}
{{ 'supersubs.js' | asset_url | script_tag }}

Caution

Make sure to include the scripts after the following code (Or whatever jQuery include your theme is using):

{{ 'jquery-1.3.2.min.js'       | asset_url | script_tag }}

6.4. Adding the basic Superfish CSS to your theme stylesheet

Browse to the file css/superfish.css and look for the segment of CSS that has this heading:

/*** ESSENTIAL STYLES ***/

You will copy that CSS segment at the bottom of our theme stylesheet. For the Reconfigured theme, the stylesheet to amend is all.css.liquid.

Adding your CSS hook

We will add a sf-menu class to the parent ul of our Main Menu. In Reconfigured, that'll give us:

<ul class="navigation sf-menu">

Adding your JavaScript

Add the following JavaScript code to the head element of theme.liquid:

<script type="text/javascript" charset="utf-8">
//<![CDATA[
jQuery(function() {
  jQuery('ul.sf-menu').superfish({
    animation: { height: 'show' }, // slide-down animation
    speed: 'fast' // faster animation speed
  });
});
//]]>
</script>

The Superfish plugin has several options worth playing with: http://users.tpg.com.au/j_birch/plugins/superfish/#options

Demo store

http://turcotte-koepp6126.myshopify.com/

Conclusion

Drop-down menus are about the hardest thing to style for a front-end designer: they are very hard to get 'just right'. Most drop-down menus we see out there are hideous. A drop-down menu is seen as fancy and cool and a must-have by many, unfortunately. A beautiful, professional theme can live without drop-down menus.

Tools

Shopify stores showcase

  • Chalk (Evolution Design)

  • nestliving (/* Yesterday I woke up sucking a lemon */)

Want to discuss this page?

Visit the Shopify Community