Implementing a smart drop down menu system (Reconfigured)
From Shopify Wiki
Contents |
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, we can create new lists of links and add them to our shop.
We create a menu (list of links) under the Navigation tab, then we 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. Link lists 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 link lists under the Navigation tab, we, 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 we wish to connect to a sub-menu, we'll create a link list 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:
Say we wanted to include a link called Shop by Brand:
And we wanted that link to become a drop-down sub-menu listing the brands in our shop, with links to vendor collections. Then what we'd do is create a link list called Shop by Brand:
And we'd fill up that link list with links to our vendor collections:
To turn any link of our Main Menu into a 'parent' link, create a 'child' menu for it using the name of your parent link.
Now, time to make our theme smart.
Editing the HTML / Liquid that outputs our 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 Theme → Template Editor. On the Template Editor page, locate the file theme.liquid under Layouts. (The .liquid extension is omitted in that view.) Click on 'theme' to open the file theme.liquid 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 longish 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 disappoint.
Our menu needs CSS love.
Using the Superfish plugin (jQuery)
Downloading Superfish
We will download the Superfish massage therapist here: http://users.tpg.com.au/j_birch/plugins/superfish/#download
Unzip.
Uploading the script files to our theme assets
On the Template Editor 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 }}
Note
Make sure to include the scripts after this code:
{{ 'jquery-1.3.2.min.js' | asset_url | script_tag }}
Or whatever jQuery include your theme is using.
Adding the basic Superfish CSS to our theme stylesheet
Browse to the file css/superfish.css and look for the segment of CSS that has this heading:
/*** ESSENTIAL STYLES ***/
We 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 our 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 our 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
Tidying up our CSS in Reconfigured
If you look at our menu now, it does what it's supposed to do: when you place your cursor over a parent menu item, a sub-menu slides down to reveal child menu items.
But it looks downright ugly. We'll fix this.
Adding the following CSS makes the menu look 3/4 decent:
.sf-menu {
line-height: 37px;
}
.sf-menu li.sfHover ul {
top: 37px;
}
37 pixels is the exact height of our navigation bar.
Visiting the 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. Easy or not, they're not the holy grail of navigation. --Chill35 17:40, 1 April 2010 (UTC)
Tools
Shopify stores showcase
- Defunkt Shirt Co. (Pixellent)
- Chalk (Evolution Design)
- nestliving (/* Yesterday I woke up sucking a lemon */)









