diff --git a/src/components/dropdown-menu/DropdownMenuSubContent.vue b/src/components/dropdown-menu/DropdownMenuSubContent.vue
index ddd7d6d..a52d660 100644
--- a/src/components/dropdown-menu/DropdownMenuSubContent.vue
+++ b/src/components/dropdown-menu/DropdownMenuSubContent.vue
@@ -1,6 +1,6 @@
@@ -30,7 +41,7 @@ const { alignOffset, ready } = useSubmenuAlignment(currentElement)
v-bind="forwarded"
:align-offset="props.alignOffset ?? alignOffset"
:style="{ visibility: ready ? undefined : 'hidden' }"
- :class="cn(menuWidthClass, menuContentClass, menuAnchoredMotionClass, 'flex min-h-0 flex-col overflow-hidden max-h-(--reka-dropdown-menu-content-available-height) origin-(--reka-dropdown-menu-content-transform-origin)', props.class)"
+ :class="cn(menuWidthClass, menuContentClass, menuAnchoredMotionClass, 'flex min-h-0 flex-col overflow-hidden max-h-(--reka-dropdown-menu-content-available-height) origin-(--reka-dropdown-menu-content-transform-origin)', props.class, !motionReady && 'animate-none! opacity-0')"
>
diff --git a/src/lib/useSubmenuAlignment.ts b/src/lib/useSubmenuAlignment.ts
index ec26946..13b5bb5 100644
--- a/src/lib/useSubmenuAlignment.ts
+++ b/src/lib/useSubmenuAlignment.ts
@@ -17,8 +17,15 @@ export function useSubmenuAlignment(content: Readonly[ 0) {
+ // Rects include viewport scrolling; alignment needs the row's position
+ // in the unscrolled content, including any nested scroll containers.
+ let scrollOffset = 0
+ for (let parent = first.parentElement; parent; parent = parent.parentElement) {
+ scrollOffset += parent.scrollTop
+ if (parent === element) break
+ }
alignOffset.value = trigger.offsetHeight / 2
- - (first.getBoundingClientRect().top - bounds.top) / scale - first.offsetHeight / 2
+ - (first.getBoundingClientRect().top - bounds.top) / scale - scrollOffset - first.offsetHeight / 2
}
}
ready.value = true
]