Hover-Down Submenus for Casper Here

Whoah this is the first I’ve seen of a new menu in Casper!

Can you point me to any Documentation so I can read about it?

1 Like

Nothing… only this :slight_smile:

Fantabulous to have (what I would call) a click-down overflow menu addition to the new Casper version!!!

Here below I’ve simplified the CSS for this (what I will call) hover-down hierarchical submenus

(I hope that Team Ghost will build this type of menu into Casper as an option as well! Better yet, I would like to see both menu types being available as options in the core theme settings so they would be built-in options for all themes.)

<style>

li[class*="nav-"][class*="--hasDropDown"] {
	position: relative;
}
li[class*="nav-"][class*="--hasDropDown"] a:after {
	content: "▼";
	padding-left: 5px;
	font-size: 12px;
	color: inherit;
}
li[class*="nav-"][class*="--hasDropDown"] .isDropDown a:after {
	display:none;
}
li[class*="nav-"][class*="--hasDropDown"]:focus-within > li[class*="nav-"]:after,
li[class*="nav-"][class*="--hasDropDown"]:hover > li[class*="nav-"]:after {
	background-color: transparent;
}
li[class*="nav-"][class*="--hasDropDown"]:focus-within .isDropDown,
li[class*="nav-"][class*="--hasDropDown"]:hover .isDropDown {
	opacity: 1;
	visibility: visible;
}
.isDropDown {
	z-index: 1;
	opacity: 0;
	visibility: hidden;
	position: absolute;
	margin: 0;
	max-width: unset;
	list-style: none;
	/* The padding inside the drop down (the space surrounding the links) */
	padding: 10px;
	/* The rounded corners of the drop down */
	border-radius: 6px;
	/* The background color of the drop down */
	background: #000;
	/* The color of the links in the drop down */
	color: inherit;
}
.isDropDown li[class*="nav-"] {
	margin-right: 0 !important;
}
.isDropDown li[class*="nav-"]:not(:last-child) {
	margin-bottom: 0;
    /* Dividers between the dropdown items */
    border-bottom: 1px solid #ddd;
}

@media (max-width: 991px) {
    #gh-head .gh-head-inner {
        grid-template-columns: 1fr;
    	height: auto;
	}
	.gh-head-open #gh-head .gh-head-menu,
    #gh-head .gh-head-menu .nav {
    	align-items: flex-start;
    	display: flex;
    	flex-direction: column;
        margin: 0 auto;
	}
    .gh-head-menu .nav li {
        text-align: left;
	}
    .gh-head-menu .nav li.hasDropDown {
        margin: 0;
    	padding: 0;
    	display: flex;
    	flex-direction: column;
    	align-items: flex-start;
	}
    .gh-head-menu ul.isDropDown {
    	list-style: none;
    	text-align: left;
    	margin: 0;
    	padding: 0 0 0 10px;
	} 
    .gh-head-menu ul.isDropDown li {
    	margin: 0;
    	padding: 0;
    	text-align: left;
	} 
    .gh-head-menu ul.isDropDown li a {
    	font-size: 2rem;
    	line-height: 1.5;
	}
}

</style>
1 Like

If anyone can provide guidance as to why, when the window is resized in any direction, the page needs to be refreshed again for this drop down to take effect, please do post any help or clues…

1 Like

It happens to me too… It is annoying… Sorry I can’t help, I’m not a coding expert :frowning: . Also with Casper 5.4.0, they have removed the “gh-social” div with the social network icons in the header. I’ve opened a ticket on Github…

You can watch the new Nav in my site https://hdsplus.co

OK @Joan I’ve got a new rendition of the script for the footer injection. I’ve also edited and commented a little more in the CSS.

For the script I just followed the example of the new overflow click-down menu in Casper. (The code you linked to at Added navbar options (#906) · TryGhost/Casper@cf30ada · GitHub)

Here’s what I’ve got now that’s working correctly. (This code might have extra cruft that can be removed. Hopefully someone better at JS can tell us.)

The CSS for the Site Header Code Injection…

<style>

li[class*="nav-"][class*="--hasDropDown"] {
	position: relative;
}
li[class*="nav-"][class*="--hasDropDown"] a:after {
	content: "▼";
	padding-left: 5px;
	font-size: 12px;
	color: inherit;
}
li[class*="nav-"][class*="--hasDropDown"] .isDropDown a:after {
	display:none;
}
li[class*="nav-"][class*="--hasDropDown"]:focus-within > li[class*="nav-"]:after,
li[class*="nav-"][class*="--hasDropDown"]:hover > li[class*="nav-"]:after {
	background-color: transparent;
}
li[class*="nav-"][class*="--hasDropDown"]:focus-within .isDropDown,
li[class*="nav-"][class*="--hasDropDown"]:hover .isDropDown {
	opacity: 1;
	visibility: visible;
}
.isDropDown {
	z-index: 1;
	opacity: 0;
	visibility: hidden;
	position: absolute;
	margin: 0;
	max-width: unset;
	list-style: none;
	/* The padding inside the drop down (the space surrounding the links) */
	padding: 10px;
	/* The rounded corners of the drop down */
	border-radius: 6px;
	/* The background color of the drop down */
	background: #000;
	/* The color of the links in the drop down */
	color: inherit;
}
.isDropDown li[class*="nav-"] {
	margin-right: 0 !important;
}
.isDropDown li[class*="nav-"]:not(:last-child) {
	margin-bottom: 0;
    /* Dividers between the dropdown items */
    border-bottom: 1px solid #ddd;
}

/* OPTIONAL: in mobile, left align all menu items and indent submenu items */
@media (max-width: 991px) {
    #gh-head .gh-head-inner {
        grid-template-columns: 1fr;
    	height: auto;
	}
	.gh-head-open #gh-head .gh-head-menu,
    #gh-head .gh-head-menu .nav {
    	align-items: flex-start;
    	display: flex;
    	flex-direction: column;
        margin: 0 auto;
	}
    .gh-head-menu .nav li {
        text-align: left;
	}
    .gh-head-menu .nav li.hasDropDown {
        margin: 0;
    	padding: 0;
    	display: flex;
    	flex-direction: column;
    	align-items: flex-start;
	}
    .gh-head-menu ul.isDropDown {
    	list-style: none;
    	text-align: left;
    	margin: 0;
    	padding: 0 0 0 10px;
	}
    .gh-head-menu ul.isDropDown li {
    	margin: 0;
    	padding: 0;
    	text-align: left;
	}
    .gh-head-menu ul.isDropDown li a {
    	font-size: 2rem;
    	line-height: 1.5;
	}
}
    
</style>

The script for the Site Footer Code Injection…

<script>
    
(function () {
    const mediaQuery = window.matchMedia('(max-width: 991px)');
    
    // IMPORTANT: For themes other than Casper, change the selector just below to select your theme's header menu selector
    const menu = document.querySelector('.gh-head-menu');
    const nav = menu.querySelector('.nav');
    if (!nav) return;

    // IMPORTANT: For themes other than Casper, change the selector just below to select your theme's header logo selector
    const logo = document.querySelector('.gh-head-logo');
    const navHTML = nav.innerHTML;

    if (mediaQuery.matches) {
        const items = nav.querySelectorAll('li');
        items.forEach(function (item, index) {
            item.style.transitionDelay = 0.03 * (index + 1) + 's';
        });
    }
    
    const makeHoverdown = function () {
        if (mediaQuery.matches) return;

        var dropDown_list = [],
        latest_navigation_item,
        // IMPORTANT: For themes other than Casper, change the selector just below to select your theme's header menu item selector 
        nav_list = document.querySelectorAll('.gh-head-menu li');
        var newMenuList = [];
        var menuTree = {};

        nav_list.forEach( (item, index) => {
            if(item.childNodes[0].innerText.startsWith('-')) {
                if(menuTree[newMenuList.length - 1]) {
            menuTree[newMenuList.length - 1].push(item);
                } else {
            menuTree[newMenuList.length - 1] = [item];
            }
        } else {
        newMenuList.push(item);
        }
        });
        
        nav_list = newMenuList.map((item, index) => {
        if(menuTree[index]) {
            let dropdown = document.createElement('ul');
            dropdown.className = 'isDropDown';
            menuTree[index].forEach(child => {
                dropDown_item_text = child.childNodes[0].innerText;
                child.childNodes[0].innerText = dropDown_item_text.replace('- ', '');
                dropdown.appendChild(child);
            });
        item.className += '--hasDropDown';
        item.appendChild(dropdown);
        }
        return item;
        });
    }

    imagesLoaded(logo, function () {
        makeHoverdown();
    });

    window.addEventListener('resize', function () {
        setTimeout(function () {
            nav.innerHTML = navHTML;
            makeHoverdown();
        }, 1);
    });

})();
</script>
1 Like

You are a genius @denvergeeks
It works! :smiley:

@Joan, we did it together – kudos to us both! It was a fun learning adventure, no?

Where else can a person receive such a kind compliment for simply standing on the shoulders of giants? (The giants here are the core developers and other contributors here who provided the building blocks we used.) Open-source ROCKS!!!

2 Likes

First of all, Merry Christmas! :slight_smile:
I found a “bug” with your code.

If you put the iPhone in landscape mode, the menu looks terrible. Without style.

I think more resolutions should be added to this part of the code.

/* OPTIONAL: in mobile, left align all menu items and indent submenu items */
@media (max-width: 991px) {

Thanks for all @denvergeeks

@Joan I cannot reproduce what you are seeing – here is how I see your site on my iPhone 13 Pro…


What do you want it to look like?

Try Changing the iPhone to landscape mode with the “megamenu” closed

https://images.squarespace-cdn.com/content/v1/5aef2fad9d5abb57b704f0e2/1557871541060-X52L3HR5TY0W1U2TMPN8/Portrait+Landscape.jpg

This one is a snapped screenshot directly on my iPhone…

This one is using the same tool as my pics above…

I’m not sure if it might be related, but your home page is crazy-slow loading…

https://gtmetrix.com/reports/www.hdsplus.co/7w9L3Rub/

It’s strange…
All of Your actual Code injection is like this, right?

https://forum.ghost.org/t/hover-down-submenus-for-casper-here/34010/22

I will look the page speed, but on my iPhone 14 Pro Max with landscape mode only, the menu looks wrong As I have shown you in the previous pictures. I will continue testing…

Yes @Joan – I just now freshly copied/pasted in that very code you linked to above and added the navigation menu items into my cleanly-installed Casper testing site at https://casper.ghost.pub

Here are current screenshots of the…

Site Code Injections…

Navigation Items…

@Joan did this code work out for your purposes?

Hi @denvergeeks
As I told you earlier, in panorama view on the iPhone 14 Pro Max, the menu looks bad. I have tried to install another instance of Ghost with the default Casper Theme and also is wrong on my case…

I still cannot reproduce your problem except for on your own site.

On all of my devices and browsers this menu code works on my clean Version: 5.34.0 with Casper test site:

Please check on all your devices this clean install using the Casper theme. Other than the CSS and JS in the site’s header and footer code injection as instructed in this post, there are no modifications to the theme.

Please take your screenshots on that site if you find any issues.

1 Like

On your site looks good!
I tried now another clean instance with the latest Ghost version and Casper Theme by default (without any modifications).
Could you check in detail the code used in your test web if there is something different?
I don’t understand…
In one of the videos, I show the Code Injection. You will see that there is only your code.
Look the video i maked with my iPhone and Mac:

Mac view
iPhone view

Hey denvergeeks, first just want to say thanks so much for this piece of code.

I’m having an issue with my dropdown which pops up when using a tablet to browse the site. Essentially the dropdown menu isn’t playing nice with Casper’s built in dropdown menu. Some of the child menus will end up being put into Casper’s menu.

For example, let’s say there is a parent element with child A, B, and C. Depending on where the menu is put, child B and C will be placed under the Casper menu, and only A will appear as a submenu under the parent.

Another issue is that the submenu doesn’t appear to work under some window widths. Here is a screenshot of the demo site you linked to demonstrate it:

Here’s a screenshot of the issue in that first problem I mentioned with child elements being tucked under Casper’s default dropdown menu: