Skip to content

fix(focusTrap): prevent page scroll when capturing focus in overlay#22825

Open
jlee038 wants to merge 1 commit intovuetifyjs:masterfrom
jlee038:fix/22802-vselect-scroll-on-first-open
Open

fix(focusTrap): prevent page scroll when capturing focus in overlay#22825
jlee038 wants to merge 1 commit intovuetifyjs:masterfrom
jlee038:fix/22802-vselect-scroll-on-first-open

Conversation

@jlee038
Copy link
Copy Markdown

@jlee038 jlee038 commented Apr 30, 2026

Description

fixes #22802

When captureFocus redirects focus into an overlay's content element, focus() was called without { preventScroll: true }. If the overlay has not yet been positioned by updateLocation (ResizeObserver, async), the content element is at its default position (top: 0), causing the browser to scroll the page to the top to bring the focused element into view.

This is most visible when transition is disabled (:transition="false"), because the default VDialogTransition sets visibility: hidden during the enter animation which normally prevents the browser from scrolling to a hidden element — masking the bug.

The fix adds { preventScroll: true } to all three focus() calls in useFocusTrap because focus trap redirections shouldn't cause unintended page scroll. Intentional scrolls are handled elsewhere (e.g. scrollToIndex(), scrollIntoView()).

Markup:

<template>
  <v-app>
    <v-main>
      <v-container>
        <p v-for="n in 50" :key="n" class="my-1">Filler line {{ n }}</p>

        <div class="d-flex flex-column ga-3">
          <v-select
            v-for="n in 3"
            :key="n"
            v-model="vals[n - 1]"
            :items="items"
            :label="`Select ${n} — first time opening will scroll to top`"
            :transition="false"
            density="compact"
            variant="outlined"
            hide-details
          />
        </div>

        <p v-for="n in 10" :key="`b${n}`" class="my-1">Content below {{ n }}</p>
      </v-container>
    </v-main>
  </v-app>
</template>

<script setup>
  import { ref } from 'vue'

  const vals = ref([null, null, null])
  const items = ['Option A', 'Option B', 'Option C', 'Option D', 'Option E']
</script>

<style>
html,
body,
.v-application,
.v-main {
  overflow: visible !important;
  height: auto !important;
}
</style>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug Report][4.0.5] Sudden scroll to top of page when v-select transition is off

1 participant