Mobile Toolkit: Off-canvas Sliders

Mobile toolbox

On a mobile website I recently built I had two sliders. The first was the main navigation menu, and the second was a product filter. They used similar CSS techniques and had to be coordinated with each other, as they both occupied the same off-canvas area to the left of the visible content.

The Off-canvas Navigation

I built the off-canvas navigation first, since it is fundamental to the site’s framework. I used the standard checkbox method to achieve this with CSS rather than JavaScript, because JavaScript tends to have a bigger impact on performance than CSS and can easily grow to a huge size if not carefully controlled. For those not familiar with this technique it uses a checkbox, a label and an adjacent sibling. The checkbox is hidden and its label is the menu icon/link. When the label is clicked it toggles the :checked state of the checkbox. The main content area is a direct sibling of the checkbox, allowing it to respond to this state via CSS, using the adjacent sibling selector (“+”). Briefly, it looks like this:

checkbox:checked + #contentWrapper { left: 75%; transition: left 0.4s; }

The important thing to remember is that for the label to activate the checkbox the two must be linked, as they are not siblings: The checkbox is above the main content area and the label is inside the content area. They are linked by matching the “for” attribute on the label to the checkbox’s ID:

<input id="menuTrigger" type="checkbox"/>
<label for="menuTrigger">Menu</label>

I dressed it up with a glyph from FontAwesome and added some CSS styling. Here’s what that looks like when completed:

See the Pen Mobile Off-canvas Navigation by Connie Finkelman (@pixelslave) on CodePen.21122

The Filter Menu

Next comes the filter. The filter is a side column on the desktop site that lets the user narrow their search results by making selections from a list of attributes. There is no room for a side column on a mobile device, and it would be useless if it flowed after the content. It is too complex to be replaced with a select element. It has to be either a pop up (modal window) or a slide out.

I can make a simple HTML list and activate it with a button:

<span class="button">Show Filter</span> <div class="filter-options"> <ul> <li>[options]</li> ...

It also needs to have a mask behind it to dim and deactivate the page allowing the user to focus on this element. Typically this would be done with a plugin, such as jQuery UI, which automatically adds the mask. But I really don’t want the bulk of that plugin! Instead, I make the mask with CSS by using the :before pseudo-element and giving it a fixed position. I created the class “mask” because I may use this same tactic on a different element later. I can use the same checkbox scheme for the filter slider as I did on the nav.

It is not possible to activate the main navigation menu when the filter is open because the mask blocks the click. However when the menu is open part of the filter button shows and that is clickable. If the user clicked it the filter’s mask would block the user from closing the nav and they might have to refresh the page to continue. For that reason, I want to be sure that the filter can not be activated when the menu is open. That’s easily accomplished with the “pointer-event” CSS attribute. I can inherit from the #contentWrapper div in its open state (using the :checked sibling relationship) and the trigger for the filter is its child, so will also inherit from that state:

#menuTrigger:checked + #contentWrapper .filter-wrapper{ pointer-events: none; }

One final thing I have to do is hide the filter slider content when the menu is showing. It is ofter longer than the navigation and it will cause that area to be taller than the space needed by the menu. You would probably be able to see it when scrolling. I can’t hide it by default and show it when the slide is triggered. That would kill the animation because it would not show until after the transition completed. Instead I hide it when the menu is showing—using selectors similar to the CSS above, but with a different child. Below is the completed code.

See the Pen Mobile sliders by Connie Finkelman (@pixelslave) on CodePen.21122

Leave a Reply