ui
ui copied to clipboard
NavigationMenuContent not appearing under the NavigationMenuItem
I have tried multiple times even reusing the exact example show in the (docs)[https://ui.shadcn.com/docs/components/navigation-menu] and still nothing I even went as far as starting a new project with
pnpm create next-app -e https://github.com/shadcn/next-template
I also tried manually installing everything you get the point. please any other ideas
@crazycodestar I had this same issue. It looks like in the navigation-menu.tsx file that is created under the components/ui folder has a left-0
attribute for the className of NavigationMenuViewport. I removed that, and now they're centered under the trigger text. Let me know if you're still having the issue or if it worked. Below is line 86 with the updated className:
<div className={cn("absolute top-full flex justify-center")}>
I also realized another thing. I tried increasing the number of dropdown menu's in the navbar. That's when I realized that the dropdowns aren't coming under each dropdown button. Rather it's coming down at the center of the entire dropdownMenuList
Yeah, you're right. I'll try to mess with it more later but hopefully someone that does front-end more regularly than me has a solution to share as well.
I'm having the same issue, anyone found a way to fix it?
After playing with it more, I realized what is actually so great about it - it's the modularity of the components themselves. How I ended up using it was wrapping my menu in a nav tag with some flex attributes, and then the NavigationMenu and NavigationMenuItems themselves in a div that uses a grid. For example, this is how my return in my Navbar.tsx file is structured:
<header className="relative isolate z-10 bg-white shadow-sm">
<nav className="mx-auto flex max-w-7xl items-center justify-between p-3 lg:px-8" aria-label="Global">
<div className="flex">
...logo.....
</div>
<div className="hidden lg:grid lg:justify-items-start">
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
....content.....
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
</div>
<div className="hidden lg:grid lg:justify-items-end">
...profile drop down.......
</div>
</nav>
</header>
Now please take the above Tailwind styling with a grain of salt because I'm no frontend guy by any means and that's just what worked for me, but it's the ability to use the tags in your own header/div styling that makes them so powerful. Hope this helps and let me know if you have any clarifying questions.
For reference, my navbar looks like this:
-left-[25%] -right-[25%]
will help centering viewport.
But there are caviats:
If your viewport (NavigationMenuContext) is too wide (for example 700px) or if your menu list is too short (NavigationMenuList), viewport will be trunctuated. Then you might set it to -left-[50%] -right-[50%]
or more, but then scrollboxes will appear on narrow screens. And overall layout will overflow right and down.
Line 88 in navigation-menu.tsx
will look like this:
<div className={cn("absolute -left-[25%] -right-[25%] top-full flex justify-center")}>
Came across this myself recently, made a minimal reproduction repository in case it helps anyone trying for a fix - https://github.com/AdiRishi/shadcn-navbar-bug-demo
Quick video to demo the issue
Also running into it
This might not be the right way to do it, but it works for me. If I wrap each <DropdownMenuItem>
that had a dropdown with it's own <NavigationMenu>
it seems to force the dropdown to appear under the trigger.
See the pull request: https://github.com/AdiRishi/shadcn-navbar-bug-demo/pull/1/files
function DropdownMenuItem({ itemText }: { itemText: string }) {
return (
<NavigationMenu> {/* Added */}
<NavigationMenuItem>
<NavigationMenuTrigger>{itemText}</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
{DROPDOWN_ITEM_DATA.map((component) => (
<ListItem
key={`${itemText}${component.title}`}
title={component.title}
href={component.href}
>
{component.description}
</ListItem>
))}
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenu> {/* Added */}
);
}
@crazycodestar I had this same issue. It looks like in the navigation-menu.tsx file that is created under the components/ui folder has a
left-0
attribute for the className of NavigationMenuViewport. I removed that, and now they're centered under the trigger text. Let me know if you're still having the issue or if it worked. Below is line 86 with the updated className:
<div className={cn("absolute top-full flex justify-center")}>
This worked for me
This might not be the right way to do it, but it works for me. If I wrap each
<DropdownMenuItem>
that had a dropdown with it's own<NavigationMenu>
it seems to force the dropdown to appear under the trigger.See the pull request: https://github.com/AdiRishi/shadcn-navbar-bug-demo/pull/1/files
function DropdownMenuItem({ itemText }: { itemText: string }) { return ( <NavigationMenu> {/* Added */} <NavigationMenuItem> <NavigationMenuTrigger>{itemText}</NavigationMenuTrigger> <NavigationMenuContent> <ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] "> {DROPDOWN_ITEM_DATA.map((component) => ( <ListItem key={`${itemText}${component.title}`} title={component.title} href={component.href} > {component.description} </ListItem> ))} </ul> </NavigationMenuContent> </NavigationMenuItem> </NavigationMenu> {/* Added */} ); }
This solves the positioning relative to the trigger nice! But breaks the slide effect because you are no longer sharing the same viewport...
Issue persists. Even after removing left-0
from the NavigationMenuViewport className, if you have multiple dropdown triggers each dropdown menu appears at the same place.
This might not be the right way to do it, but it works for me. If I wrap each
<DropdownMenuItem>
that had a dropdown with it's own<NavigationMenu>
it seems to force the dropdown to appear under the trigger.See the pull request: https://github.com/AdiRishi/shadcn-navbar-bug-demo/pull/1/files
function DropdownMenuItem({ itemText }: { itemText: string }) { return ( <NavigationMenu> {/* Added */} <NavigationMenuItem> <NavigationMenuTrigger>{itemText}</NavigationMenuTrigger> <NavigationMenuContent> <ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] "> {DROPDOWN_ITEM_DATA.map((component) => ( <ListItem key={`${itemText}${component.title}`} title={component.title} href={component.href} > {component.description} </ListItem> ))} </ul> </NavigationMenuContent> </NavigationMenuItem> </NavigationMenu> {/* Added */} ); }
This worked for me.
Managed to get the content position to stick under the corresponding trigger element. If anyone needs it, I made a gist over here.
This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.
Definitely closed by accident. Jeez, auto-close bots are the worst.