Skip to content

Instantly share code, notes, and snippets.

@damiencarbery
Created March 12, 2026 14:38
Show Gist options
  • Select an option

  • Save damiencarbery/8d2b77bcda754040727a8329eec3f867 to your computer and use it in GitHub Desktop.

Select an option

Save damiencarbery/8d2b77bcda754040727a8329eec3f867 to your computer and use it in GitHub Desktop.
Sticky Navigation - stick header area too - To set the navigation and header as sticky in GeneratePress the height of the header is needed for the navigation 'top' property. Also scroll to # anchors (less height of sticky header and sticky nav).
<?php
/*
Plugin Name: Sticky Navigation - stick header area too
Plugin URI: https://www.damiencarbery.com/
Description: To set the navigation and header as sticky in GeneratePress the height of the header is needed for the navigation 'top' property. Also scroll to # anchors (less height of sticky header and sticky nav).
Author: Damien Carbery
Version: 0.3.20260312
*/
defined( 'ABSPATH' ) || exit;
add_action( 'wp_footer', 'to_make_nav_sticky' );
function to_make_nav_sticky() {
$module_active = null; // Different CSS for when GP Premium is active.
$device_type = 'all'; // Slightly different JS depending on GP Premium Menu Plus Sticky Nav settings.
// Check whether GP Premium plugin Menu Plus module active.
if ( !function_exists( 'generate_menu_plus_get_defaults' ) ) {
// Otherwise check whether GeneratePress is the active theme.
if ( ! function_exists( 'generate_setup' ) ) {
// If GeneratePress theme is not active, add a html comment for the site admin (so they know the plugin is working).
if ( current_user_can('manage_options') ) {
echo "\n<!-- Sticky Navigation: GeneratePress is not the active theme. This plugin is designed for GeneratePress theme. -->\n";
}
return;
}
else {
$module_active = 'generatepress';
}
}
else {
$module_active = 'gp_premium';
// Merge stored data with default Menu Plus settings.
$settings = wp_parse_args(
get_option( 'generate_menu_plus_settings', array() ),
generate_menu_plus_get_defaults()
);
// If it is not set or is set to Off, add a html comment for the site admin (so they know the plugin is working).
if ( !isset( $settings['sticky_menu'] ) || 'false' == $settings['sticky_menu'] ) {
if ( current_user_can('manage_options') ) {
echo "\n<!-- Sticky Navigation: GeneratePress Sticky Menu is set to 'Off'. Change to On, Mobile or Desktop for this plugin to work. -->\n";
}
return;
}
if ( 'mobile' == $settings['sticky_menu'] ) {
$device_type = 'mobile';
}
if ( 'desktop' == $settings['sticky_menu'] ) {
$device_type = 'desktop';
}
if ( 'true' == $settings['sticky_menu'] ) {
$device_type = 'all';
}
}
// GP Premium adds body classes for Sticky Nav.
if ( 'gp_premium' == $module_active ) {
?>
<style>
/* GP Premium sticky navigation styling. */
body.both-sticky-menu #masthead { top: 0; }
body.both-sticky-menu #masthead, body.both-sticky-menu #site-navigation { position: sticky; z-index: 100; }
@media (max-width: 768px) {
body.mobile-sticky-menu #masthead { top: 0; }
body.mobile-sticky-menu #masthead, body.mobile-sticky-menu #site-navigation { position: sticky; z-index: 100; }
}
@media (min-width: 769px) {
body.desktop-sticky-menu #masthead, body.both-sticky-menu #masthead { top: 0; }
body.desktop-sticky-menu #masthead, body.desktop-sticky-menu #site-navigation { position: sticky; z-index: 100; }
}
</style>
<?php
}
// There's no extra body classes so we can target #masthead and #site-navigation directly.
if ( 'generatepress' == $module_active ) {
?>
<style>
/* GeneratePress sticky navigation styling. */
#masthead { top: 0; }
#masthead, #site-navigation { position: sticky; z-index: 100; }
@media (max-width: 768px) {
#masthead { top: 0; }
#masthead, #site-navigation { position: sticky; z-index: 100; }
}
@media (min-width: 769px) {
#masthead { top: 0; }
#masthead, #site-navigation { position: sticky; z-index: 100; }
}
</style>
<?php
}
?>
<script>
// Get the height of the #masthead element (the header with logo) and set the 'top' property of #site-navigation to that height.
document.addEventListener("DOMContentLoaded", function(event) {
const device_type = '<?php echo $device_type; ?>';
if ( ( 'all' == device_type ) ||
( 'mobile' == device_type && screen.width <= 768 ) ||
( 'desktop' == device_type && screen.width > 768 ) ) {
const header_el = document.getElementById( 'masthead' );
// If the user is logged in we must include the height of the admin bar.
var wpAdminBarHeight = 0;
const wpAdminBar = document.getElementById( 'wpadminbar' );
if ( wpAdminBar ) {
wpAdminBarHeight = wpAdminBar.offsetHeight; // offsetHeight is not ideal as it excludes margin top/bottom.
}
//console.log( 'wpAdminBarHeight:', wpAdminBarHeight );
header_el.style.top = wpAdminBarHeight + 'px';
const site_nav = document.getElementById( 'site-navigation' );
site_nav.style.top = ( header_el.offsetHeight + wpAdminBarHeight ) + 'px';
//console.log( '#masthead top = ', header_el.offsetHeight );
//console.log( '#site-navigation top = ', site_nav.style.top );
// Add the classes that the GP Premium Menu Plus stickUp() JS would add.
site_nav.classList.add( 'is_stuck', 'navigation-stick', 'navigation-clone', 'sticky-navigation-transition' );
}
});
// Scroll to anchor element and reduce scroll distance by height of header and nav.
document.addEventListener('click', function (event) {
const linkTarget = event.target.getAttribute('href');
// Verify that link is not null and begins with contains anchor url (begins with #).
if (! linkTarget ) return;
if (! linkTarget.startsWith( '#' ) ) return;
// Don't follow the link
event.preventDefault();
targetID = linkTarget.substring( 1 );
if (! targetID ) return;
const targetDiv = document.getElementById( targetID );
if (! targetDiv ) return; // Quit if target anchor cannot be found.
const header_el = document.getElementById( 'masthead' );
const site_nav = document.getElementById( 'site-navigation' );
// Scroll to target Div less height of header and nav.
window.scrollTo({ behavior: 'smooth', top: targetDiv.offsetTop - header_el.offsetHeight - site_nav.offsetHeight })
}, false);
</script>
<?php
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment