diff --git a/packages/frontend/src/components/MkTooltip.vue b/packages/frontend/src/components/MkTooltip.vue
index 6104b8df72..ea39198706 100644
--- a/packages/frontend/src/components/MkTooltip.vue
+++ b/packages/frontend/src/components/MkTooltip.vue
@@ -41,6 +41,9 @@ const emit = defineEmits<{
 	(ev: 'closed'): void;
 }>();
 
+// タイミングによっては最初から showing = false な場合があり、その場合に closed 扱いにしないと永久にDOMに残ることになる
+if (!props.showing) emit('closed');
+
 const el = shallowRef<HTMLElement>();
 const zIndex = os.claimZIndex('high');
 
diff --git a/packages/frontend/src/directives/tooltip.ts b/packages/frontend/src/directives/tooltip.ts
index 5d13497b5f..373141fa35 100644
--- a/packages/frontend/src/directives/tooltip.ts
+++ b/packages/frontend/src/directives/tooltip.ts
@@ -5,7 +5,7 @@ import { defineAsyncComponent, Directive, ref } from 'vue';
 import { isTouchUsing } from '@/scripts/touch';
 import { popup, alert } from '@/os';
 
-const start = isTouchUsing ? 'touchstart' : 'mouseover';
+const start = isTouchUsing ? 'touchstart' : 'mouseenter';
 const end = isTouchUsing ? 'touchend' : 'mouseleave';
 
 export default {
@@ -63,16 +63,24 @@ export default {
 			ev.preventDefault();
 		});
 
-		el.addEventListener(start, () => {
+		el.addEventListener(start, (ev) => {
 			window.clearTimeout(self.showTimer);
 			window.clearTimeout(self.hideTimer);
-			self.showTimer = window.setTimeout(self.show, delay);
+			if (delay === 0) {
+				self.show();
+			} else {
+				self.showTimer = window.setTimeout(self.show, delay);
+			}
 		}, { passive: true });
 
 		el.addEventListener(end, () => {
 			window.clearTimeout(self.showTimer);
 			window.clearTimeout(self.hideTimer);
-			self.hideTimer = window.setTimeout(self.close, delay);
+			if (delay === 0) {
+				self.close();
+			} else {
+				self.hideTimer = window.setTimeout(self.close, delay);
+			}
 		}, { passive: true });
 
 		el.addEventListener('click', () => {