November 13, 2015 by Sridhar Katakam
/* --- Add the following in child theme’s style.css: --- */
/* Responsive Menu
--------------------------------------------- */
.sub-menu-toggle,
.menu-toggle {
display: none;
visibility: hidden;
}
@media only screen and (max-width: 880px) {
.js nav {
display: none;
position: relative;
}
.js nav .wrap {
padding: 0;
}
.js nav.pagination {
display: block;
}
.menu-toggle,
.sub-menu-toggle {
background-color: #222;
color: #fff;
display: block;
margin: 0 auto;
overflow: hidden;
text-align: center;
visibility: visible;
}
.menu-toggle {
position: relative;
right: 0;
z-index: 1000;
width: 100%;
}
.menu-toggle:before,
.menu-toggle.activated:before {
color: #fff;
content: "\f333";
display: inline-block;
font: normal 20px/1 'dashicons';
margin: 0 auto;
padding-right: 10px;
text-rendering: auto;
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
transform: translate(0, 0);
/*vertical-align: bottom;*/
vertical-align: top;
padding-top: 3px;
}
.sub-menu-toggle {
float: right;
padding: 18px;
position: absolute;
right: 0;
top: 0;
z-index: 100;
}
.sub-menu-toggle:before {
content: "\f347";
display: inline-block;
font: normal 16px/1 'dashicons';
text-rendering: auto;
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
transform: translate(0, 0);
}
.sub-menu-toggle.activated:before {
content: "\f343";
}
.js .genesis-nav-menu .menu-item {
display: block;
float: none;
position: relative;
text-align: left;
}
.js .genesis-nav-menu .menu-item:hover {
position: relative;
}
.js .genesis-nav-menu .menu-item a {
border: none;
color: #fff;
/*font-family: 'Roboto Condensed', sans-serif;*/
padding: 20px;
width: 100%;
}
.js .genesis-nav-menu .menu-item a:hover,
.js .genesis-nav-menu .sub-menu {
border: none;
}
.js .genesis-nav-menu .menu-item > a:focus ul.sub-menu,
.js .genesis-nav-menu .menu-item > a:focus ul.sub-menu .sub-menu {
left: 0;
margin-left: 0;
}
.js .genesis-nav-menu > .menu-item-has-children > a:after {
content: none;
}
.js .genesis-nav-menu .sub-menu {
clear: both;
display: none;
margin: 0;
opacity: 1;
position: static;
width: 100%;
padding-left: 20px;
}
.js .genesis-nav-menu .sub-menu .sub-menu {
margin: 0;
}
.js .genesis-nav-menu .sub-menu a {
border: none;
}
.js nav .genesis-nav-menu .menu-item .sub-menu li a,
.js nav .genesis-nav-menu .menu-item .sub-menu li a:hover,
.js nav button:hover,
.js .menu-toggle:hover,
.js .nav-primary {
background-color: #222;
color: #fff;
}
.js nav .genesis-nav-menu .menu-item .sub-menu li a:focus,
.js nav .genesis-nav-menu .menu-item a:focus,
.js nav button:focus,
.js .menu-toggle:focus {
background-color: #222;
color: #ff4800;
}
.js .nav-header .genesis-nav-menu .menu-item a,
.js .nav-secondary .genesis-nav-menu .menu-item a {
color: #333;
}
}
// Add the following in child theme’s functions.php:
// Enqueue Scripts and Styles
add_action( 'wp_enqueue_scripts', 'custom_enqueue_scripts_styles' );
function custom_enqueue_scripts_styles() {
// wp_enqueue_style( 'google-fonts', '//fonts.googleapis.com/css?family=Roboto+Condensed:300italic,700italic,700,300', array(), CHILD_THEME_VERSION );
wp_enqueue_style( 'dashicons' );
wp_enqueue_script( 'responsive-menu', get_stylesheet_directory_uri() . '/js/responsive-menu.js', array( 'jquery' ), '1.0.0', true );
$output = array(
'mainMenu' => __( 'Menu', 'my-theme-text-domain' ),
'subMenu' => __( 'Menu', 'my-theme-text-domain' ),
);
wp_localize_script( 'responsive-menu', 'ResponsiveMenuL10n', $output );
}
// Create a file named responsive-menu.js in your child theme’s js directory (create if not existing) having the following code:
( function ( document, $, undefined ) {
$( 'body' ).addClass( 'js' );
'use strict';
var responsive_menu = {},
mainMenuButtonClass = 'menu-toggle',
subMenuButtonClass = 'sub-menu-toggle';
responsive_menu.init = function() {
var toggleButtons = {
menu : $( '<button />', {
'class' : mainMenuButtonClass,
'aria-expanded' : false,
'aria-pressed' : false,
'role' : 'button'
} )
.append( responsive_menu.params.mainMenu ),
submenu : $( '<button />', {
'class' : subMenuButtonClass,
'aria-expanded' : false,
'aria-pressed' : false,
'role' : 'button'
} )
.append( $( '<span />', {
'class' : 'screen-reader-text',
text : responsive_menu.params.subMenu
} ) )
};
$( '.nav-primary, .nav-secondary, .nav-header' ).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.responsive_menu', _doResize ).triggerHandler( 'resize.responsive_menu' );
$( '.' + mainMenuButtonClass ).on( 'click.responsive_menu-mainbutton', _mainmenuToggle );
$( '.' + subMenuButtonClass ).on( 'click.responsive_menu-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 ) );
}
// check CSS rule to determine width
function _combineMenus(){
if ($( '.js nav' ).css( 'position' ) == 'relative' ){ // depends on .js nav having position: relative; in style.css
$( 'ul.menu-secondary > li' ).addClass( 'moved-item' ); // tag moved items so we can move them back
$( 'ul.menu-secondary > li' ).appendTo( 'ul.menu-primary' );
$( '.nav-secondary' ).hide();
} else {
$( '.nav-secondary' ).show();
$( 'ul.menu-primary > li.moved-item' ).appendTo( 'ul.menu-secondary' );
$( 'ul.menu-secondary > li' ).removeClass( 'moved-item' );
}
}
// 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' );
// $( 'nav.nav-primary' ).slideToggle( 'fast' ); //changed to .nav-primary since we're not toggling .nav-secondary
$this.next('nav').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 'false' === value;
});
}
$(document).ready(function () {
// run test on initial page load
// _combineMenus();
// run test on resize of the window
// $( window ).resize( _combineMenus );
responsive_menu.params = typeof ResponsiveMenuL10n === 'undefined' ? '' : ResponsiveMenuL10n;
if ( typeof responsive_menu.params !== 'undefined' ) {
responsive_menu.init();
}
});
})( document, jQuery );
https://sridharkatakam.com/accessible-responsive-menu-in-genesis/
Newer Genesis child themes like Workstation Pro and Atmosphere Pro come with responsive mobile hamburger menu code which is better than the one in older themes like Beautiful Pro or Magazine Pro in that accessibility is taken care of.
In this article I share the code taken from Workstation Pro and slightly modified so that it works for not just Primary Menu but Header Menu and Secondary Menu as well.
Due to the vast number of available Genesis child themes, it is practically not possible to come up with CSS that makes the mobile menus look good in all of them. Therefore you will need to tweak the CSS so it matches your theme/design.