Skip to content

Instantly share code, notes, and snippets.

@robincornett
Last active November 27, 2017 08:25
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save robincornett/7e6e4aa5317fd89e2cef to your computer and use it in GitHub Desktop.
Save robincornett/7e6e4aa5317fd89e2cef to your computer and use it in GitHub Desktop.
Responsive menus for HTML5 Genesis themes. with updating skip links. The skip links must follow the pattern established in Genesis core.
<?php
//do not include the opening tag!
// Required Scripts and Styles
add_action( 'wp_enqueue_scripts', 'leaven_load_scripts', 15 );
function leaven_load_scripts() {
// Responsive Navigation
wp_enqueue_style( 'fontawesome', '//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css', array(), '4.3.0' );
wp_enqueue_script( 'leaven-responsive-menu', get_stylesheet_directory_uri() . '/js/responsive-menu.js', array( 'jquery' ), '1.0.0', true );
$output = array(
'mainMenu' => __( 'Menu', 'leaven' ),
'subMenu' => __( 'Menu', 'leaven' ),
);
wp_localize_script( 'leaven-responsive-menu', 'LeavenL10n', $output );
}
<?php
// do not include the opening tag!
// Add skip link needs to secondary nav
add_filter( 'genesis_attr_nav-secondary', 'leaven_add_nav_secondary_id' );
function leaven_add_nav_secondary_id( $attributes ) {
$attributes['id'] = 'genesis-nav-secondary';
return $attributes;
}
add_filter( 'genesis_skip_links_output', 'leaven_add_nav_secondary_skip_link' );
function leaven_add_nav_secondary_skip_link( $links ) {
$new_links = $links;
array_splice( $new_links, 1 );
if ( has_nav_menu( 'secondary' ) ) {
$new_links['genesis-nav-secondary'] = __( 'Skip to secondary navigation', 'leaven' );
}
return array_merge( $new_links, $links );
}
( function ( document, $, undefined ) {
'use strict';
var leaven = {},
mainMenuButtonClass = 'menu-toggle',
subMenuButtonClass = 'sub-menu-toggle';
leaven.init = function() {
var toggleButtons = {
menu : $( '<button />', {
'class' : mainMenuButtonClass,
'aria-expanded' : false,
'aria-pressed' : false,
'role' : 'button'
} )
.append( leaven.params.mainMenu ),
submenu : $( '<button />', {
'class' : subMenuButtonClass,
'aria-expanded' : false,
'aria-pressed' : false,
'role' : 'button'
} )
.append( $( '<span />', {
'class' : 'screen-reader-text',
text : leaven.params.subMenu
} ) )
};
$( 'nav' ).before( toggleButtons.menu ); // add the main nav buttons
$( 'nav .sub-menu' ).before( toggleButtons.submenu ); // add the submenu nav buttons
$( '.' + mainMenuButtonClass ).each( _addClassID );
$( window ).on( 'resize.leaven', _doResize ).triggerHandler( 'resize.leaven' );
$( '.' + mainMenuButtonClass ).on( 'click.leaven-mainbutton', _mainmenuToggle );
$( '.' + subMenuButtonClass ).on( 'click.leaven-subbutton', _submenuToggle );
};
// add nav class and ID to related button
function _addClassID() {
var $this = $( this ),
nav = $this.next( 'nav' ),
id = 'class';
$this.addClass( $( nav ).attr( 'class' ) );
if ( $( nav ).attr( 'id' ) ) {
id = 'id';
}
$this.attr( 'id', 'mobile-' + $( nav ).attr( id ) );
}
// Change Skiplinks and Superfish
function _doResize() {
var buttons = $( 'button[id^=mobile-]' ).attr( 'id' );
if ( typeof buttons === 'undefined' ) {
return;
}
_superfishToggle( buttons );
_changeSkipLink( buttons );
_maybeClose( buttons );
}
/**
* action to happen when the main menu button is clicked
*/
function _mainmenuToggle() {
var $this = $( this );
_toggleAria( $this, 'aria-pressed' );
_toggleAria( $this, 'aria-expanded' );
$this.toggleClass( 'activated' );
$this.next( 'nav, .sub-menu' ).slideToggle( 'fast' );
}
/**
* action for submenu toggles
*/
function _submenuToggle() {
var $this = $( this ),
others = $this.closest( '.menu-item' ).siblings();
_toggleAria( $this, 'aria-pressed' );
_toggleAria( $this, 'aria-expanded' );
$this.toggleClass( 'activated' );
$this.next( '.sub-menu' ).slideToggle( 'fast' );
others.find( '.' + subMenuButtonClass ).removeClass( 'activated' ).attr( 'aria-pressed', 'false' );
others.find( '.sub-menu' ).slideUp( 'fast' );
}
/**
* activate/deactivate superfish
*/
function _superfishToggle( buttons ) {
if ( typeof $( '.js-superfish' ).superfish !== 'function' ) {
return;
}
if ( 'none' === _getDisplayValue( buttons ) ) {
$( '.js-superfish' ).superfish( {
'delay': 100,
'animation': {'opacity': 'show', 'height': 'show'},
'dropShadows': false
});
} else {
$( '.js-superfish' ).superfish( 'destroy' );
}
}
/**
* modify skip links to match mobile buttons
*/
function _changeSkipLink( buttons ) {
var startLink = 'genesis-nav',
endLink = 'mobile-genesis-nav';
if ( 'none' === _getDisplayValue( buttons ) ) {
startLink = 'mobile-genesis-nav';
endLink = 'genesis-nav';
}
$( '.genesis-skip-link a[href^="#' + startLink + '"]' ).each( function() {
var link = $( this ).attr( 'href' );
link = link.replace( startLink, endLink );
$( this ).attr( 'href', link );
});
}
function _maybeClose( buttons ) {
if ( 'none' !== _getDisplayValue( buttons ) ) {
return;
}
$( '.menu-toggle, .sub-menu-toggle' )
.removeClass( 'activated' )
.attr( 'aria-expanded', false )
.attr( 'aria-pressed', false );
$( 'nav, .sub-menu' )
.attr( 'style', '' );
}
/**
* generic function to get the display value of an element
* @param {id} $id ID to check
* @return {string} CSS value of display property
*/
function _getDisplayValue( $id ) {
var element = document.getElementById( $id ),
style = window.getComputedStyle( element );
return style.getPropertyValue( 'display' );
}
/**
* Toggle aria attributes
* @param {button} $this passed through
* @param {aria-xx} attribute aria attribute to toggle
* @return {bool} from _ariaReturn
*/
function _toggleAria( $this, attribute ) {
$this.attr( attribute, function( index, value ) {
return _ariaReturn( value );
});
}
/**
* update aria-xx value of an attribute
* @param {aria-xx} value passed from function
* @return {bool}
*/
function _ariaReturn( value ) {
return 'false' === value ? 'true' : 'false';
}
$(document).ready(function () {
leaven.params = typeof LeavenL10n === 'undefined' ? '' : LeavenL10n;
if ( typeof leaven.params !== 'undefined' ) {
leaven.init();
}
});
})( document, jQuery );
/* # Responsive Navigation
---------------------------------------------------------------------------------------------------- */
/* Navigation toggles
--------------------------------------------- */
.sub-menu-toggle,
.menu-toggle {
display: none;
visibility: hidden;
}
@media only screen and (max-width: 800px) {
nav {
display: none;
position: relative;
}
nav .wrap {
padding: 0;
}
nav.pagination {
display: block;
}
.menu-toggle,
.sub-menu-toggle {
display: block;
visibility: visible;
overflow: hidden;
margin: 0 auto;
font-size: 20px;
font-weight: 700;
text-align: center;
background-color: transparent;
}
.menu-toggle {
background-color: #333;
position: relative;
padding: 20px 12px;
right: 0;
z-index: 1000;
color: white;
width: 100%;
}
.menu-toggle:before,
.menu-toggle.activated:before {
display: inline-block;
font: normal normal normal 20px FontAwesome;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
transform: translate(0, 0);
content: "\f0c9";
padding-right: 12px;
}
.sub-menu-toggle {
background: transparent;
float: right;
position: absolute;
top: 0;
right: 0;
padding: 18px;
z-index: 100;
}
.sub-menu-toggle:before {
display: inline-block;
font: normal normal normal 16px FontAwesome;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
transform: translate(0, 0);
content: "\f107";
}
.sub-menu-toggle.activated:before {
content: "\f106";
}
.genesis-nav-menu .menu-item {
display: block;
position: relative;
text-align: left;
}
.genesis-nav-menu .menu-item a {
border-top: 1px solid rgba(0, 0, 0, 0.1);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
width: 100%;
padding: 20px;
}
.genesis-nav-menu .menu-item:hover {
position: relative;
}
.genesis-nav-menu .menu-item > a:focus ul.sub-menu,
.genesis-nav-menu .menu-item > a:focus ul.sub-menu .sub-menu {
left: 0;
margin-left: 0;
}
.genesis-nav-menu > .menu-item-has-children > a:after {
content: none;
}
.genesis-nav-menu .sub-menu {
display: none;
clear: both;
margin: 0;
position: static;
width: 100%;
opacity: 1;
}
.genesis-nav-menu .sub-menu .sub-menu {
margin: 0;
}
.genesis-nav-menu .sub-menu a {
border-left: none;
border-right: none;
padding-left: 40px;
color: #eee;
}
.nav-primary .genesis-nav-menu .sub-menu a {
background-color: #333;
color: #eee;
}
}
@hellokellybrito
Copy link

Hey Robin,
I've used the code, but now I have no menu at all... any idea of what I could be doing wrong?
I just copied + pasted the code, and removed nothing at all from my original code.

Sorry, I'm not great at .js or .php, so any help is appreciated. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment