Skip to content

Desktop nav: fat menu does not dismiss on hovering a sibling top item, and <a class="item"> top links have no hover underline #907

Description

@mpalomaki

Summary

Two small, related defects in the desktop navigation, both visible on plone.org:

  1. The fat menu doesn't dismiss when the pointer moves onto a different top-level item. The menu is click-controlled with no hover handling, so an open panel stays open while the pointer is elsewhere in the nav, and the open item's .active underline coexists with the hovered item's :hover underline — two indicators at once.
  2. Top-level <a class="item"> items get no hover/active underline, because _header.scss disables the underline pseudo-element for a.item. The <button> items (fat-menu mode) keep it, so the affordance is inconsistent — and a nav rendered entirely as links (fat menu off) has no hover underline on any top item.

Neither is a crash; both are affordance/interaction issues.

Environment: observed in 8.0.0-alpha.28, confirmed still present on main / 8.0.0a31.

Reproduction

1 — panel doesn't dismiss on hover-away:

  1. Fat menu enabled. Click a top item that has children → its panel opens and its label gains the accent underline.
  2. Without clicking, move the pointer onto a different top-level item.
  3. The panel stays open, the first item keeps its underline, and the hovered item shows its own — two underlines, and a panel open over content the pointer has left.

2 — plain-link top item has no hover underline:

  1. Render a top item as a plain link (<a class="item"> rather than a fat-menu <button>) — the default for every top item when the fat menu is off.
  2. Hover it → no underline, whereas a <button> item in the same bar underlines on hover.

Root cause

1 — Navigation.tsx is click-only. Open/close is driven by onClick={() => openMenu(index)} on the top <button>, plus a document click-outside handler and the panel's own close affordances. There is no onMouseEnter on the top items, so moving to a sibling neither closes the open panel nor transfers the indicator, and the .active (open) and :hover (pointed) underlines can render simultaneously. (The recent closing-logic work, #835 / #883, addressed scrollbar clicks, not pointer-move dismissal.)

2 — _header.scss suppresses the underline for a.item. The underline is an absolute-positioned ::before on .item that blockifies and renders for <button>, but is explicitly turned off for <a>:

ul.desktop-menu {
  & > li > a {
    &.item {
      &.active::before,
      &:hover::before {
        display: none;
      }
    }
  }
}

Since Navigation.tsx renders top items as <button> only when hasFatMenu is true and as plain <a class="item"> (NavItem) otherwise, plain-link top items never get the hover underline — every top item in fat-menu-off mode, or leaf/link items in a mixed nav.

Suggested fix

1 — dismiss the open panel when the pointer enters a different top item:

const dismissIfHoveringOther = (index: number) => {
  if (currentOpenIndex !== null && currentOpenIndex !== index) closeMenu();
};
// ...
<li key={item.url} onMouseEnter={() => dismissIfHoveringOther(index)}>

Click still opens; hover never auto-opens; moving into the open panel doesn't close it (the panel is a child of the open item's <li>, so no mouseEnter fires on a different item). If you'd rather hover switches to the hovered item's menu, that resolves the coexisting-indicator problem too — your call on the interaction.

2 — let a.item keep the hover underline (whether a plain link should also show a persistent current-page underline via .active is a separate design choice; the hover affordance shouldn't differ from the buttons):

ul.desktop-menu > li > a.item:hover::before {
  display: block;
}

Happy to open a PR for the CSS one-liner (fix 2) if that's useful — fix 1 is more of a design call, which is why this is an issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions