diff --git a/app.vue b/app.vue
index 796a8125..586dc3b4 100644
--- a/app.vue
+++ b/app.vue
@@ -19,6 +19,9 @@ isDark.value
   <NuxtLayout>
     <NuxtPage />
   </NuxtLayout>
+  <TeleportTarget
+    id="teleport-end"
+  />
 </template>
 
 <style>
diff --git a/components/modal/ModalDialog.vue b/components/modal/ModalDialog.vue
index 9b888d22..12290509 100644
--- a/components/modal/ModalDialog.vue
+++ b/components/modal/ModalDialog.vue
@@ -96,29 +96,31 @@ function onTransitionEnd() {
 </script>
 
 <template>
-  <div
-    v-if="isVisible"
-    class="scrollbar-hide"
-    fixed top-0 bottom-0 left-0 right-0 z-20000 overscroll-none overflow-y-scroll
-    :class="modelValue ? '' : 'pointer-events-none'"
-  >
-    <!-- The style `scrollbar-hide overscroll-none overflow-y-scroll` and `h="[calc(100%+0.5px)]"` is used to implement scroll locking, -->
-    <!-- corresponding to issue: #106, so please don't remove it. -->
+  <SafeTeleport to="#teleport-end">
     <div
-      bg-base bottom-0 left-0 right-0 top-0 absolute transition-opacity duration-500 ease-out
-      h="[calc(100%+0.5px)]"
-      :class="isOut ? 'opacity-0' : 'opacity-85'"
-      @click="close"
-    />
-    <div
-      ref="target"
-      bg-base border-base absolute transition-all duration-200 ease-out transform
-      :class="`${positionClass} ${transformClass}`"
-      @transitionend="onTransitionEnd"
+      v-if="isVisible"
+      class="scrollbar-hide"
+      fixed top-0 bottom-0 left-0 right-0 z-10 overscroll-none overflow-y-scroll
+      :class="modelValue ? '' : 'pointer-events-none'"
     >
-      <slot />
+      <!-- The style `scrollbar-hide overscroll-none overflow-y-scroll` and `h="[calc(100%+0.5px)]"` is used to implement scroll locking, -->
+      <!-- corresponding to issue: #106, so please don't remove it. -->
+      <div
+        bg-base bottom-0 left-0 right-0 top-0 absolute transition-opacity duration-500 ease-out
+        h="[calc(100%+0.5px)]"
+        :class="isOut ? 'opacity-0' : 'opacity-85'"
+        @click="close"
+      />
+      <div
+        ref="target"
+        bg-base border-base absolute transition-all duration-200 ease-out transform
+        :class="`${positionClass} ${transformClass}`"
+        @transitionend="onTransitionEnd"
+      >
+        <slot />
+      </div>
     </div>
-  </div>
+  </SafeTeleport>
 </template>
 
 <style socped>
diff --git a/package.json b/package.json
index fbad2a1d..8c73b4ca 100644
--- a/package.json
+++ b/package.json
@@ -65,7 +65,8 @@
     "ufo": "^1.0.0",
     "unplugin-auto-import": "^0.12.0",
     "vite-plugin-inspect": "^0.7.9",
-    "vitest": "^0.25.3"
+    "vitest": "^0.25.3",
+    "vue-safe-teleport": "^0.1.1"
   },
   "dependencies": {
     "vue-virtual-scroller": "2.0.0-beta.3"
diff --git a/plugins/vue-safe-teleport.ts b/plugins/vue-safe-teleport.ts
new file mode 100644
index 00000000..dcecd124
--- /dev/null
+++ b/plugins/vue-safe-teleport.ts
@@ -0,0 +1,6 @@
+import VueSafeTeleport from 'vue-safe-teleport'
+import { defineNuxtPlugin } from '#app'
+
+export default defineNuxtPlugin((nuxtApp) => {
+  nuxtApp.vueApp.use(VueSafeTeleport)
+})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index cfaa0299..41c60359 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -51,6 +51,7 @@ specifiers:
   unplugin-auto-import: ^0.12.0
   vite-plugin-inspect: ^0.7.9
   vitest: ^0.25.3
+  vue-safe-teleport: ^0.1.1
   vue-virtual-scroller: 2.0.0-beta.3
 
 dependencies:
@@ -107,6 +108,7 @@ devDependencies:
   unplugin-auto-import: 0.12.0
   vite-plugin-inspect: 0.7.9
   vitest: 0.25.3
+  vue-safe-teleport: 0.1.1
 
 packages:
 
@@ -7883,6 +7885,12 @@ packages:
       vue: 3.2.45
     dev: true
 
+  /vue-safe-teleport/0.1.1:
+    resolution: {integrity: sha512-fHA4mod2oF7am2yEUtT0CsxAwfNBt6hWuYTVWzGxrY8vzxxgHMFnPjdZTKl01qGcKEMYYO38LmWizL7oGMVPGw==}
+    peerDependencies:
+      vue: ^3.2.0
+    dev: true
+
   /vue-virtual-scroller/2.0.0-beta.3:
     resolution: {integrity: sha512-k0hTAkZRmm3TXpfhW5Ig1fd8VV7+CmgnkebbQ4Uw6wnuQF52YJoaMQTFD3IV/Qi2WNadDB4ETrLUbVdnWboSjg==}
     peerDependencies: