diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl
index 38c18b6566..297b62edd9 100644
--- a/templates/repo/diff/box.tmpl
+++ b/templates/repo/diff/box.tmpl
@@ -24,7 +24,7 @@
 					{{svg "octicon-diff" 16 "gt-mr-2"}}{{.locale.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion | Str2html}}
 				</div>
 			</div>
-			<div class="diff-detail-actions gt-df gt-ac gt-w-100">
+			<div class="diff-detail-actions gt-df gt-ac">
 				{{if and .PageIsPullFiles $.SignedUserID (not .IsArchived)}}
 					<progress id="viewed-files-summary" class="gt-mr-2" value="{{.Diff.NumViewedFiles}}" max="{{.Diff.NumFiles}}"></progress>
 					<label for="viewed-files-summary" id="viewed-files-summary-label" class="gt-mr-3 gt-f1" data-text-changed-template="{{.locale.Tr "repo.pulls.viewed_files_label"}}">
diff --git a/templates/repo/diff/new_review.tmpl b/templates/repo/diff/new_review.tmpl
index 52aff10e29..af970a67b6 100644
--- a/templates/repo/diff/new_review.tmpl
+++ b/templates/repo/diff/new_review.tmpl
@@ -4,7 +4,7 @@
 		<span class="ui small label review-comments-counter" data-pending-comment-number="{{.PendingCodeCommentNumber}}">{{.PendingCodeCommentNumber}}</span>
 		{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 	</button>
-	<div class="review-box-panel gt-hidden">
+	<div class="review-box-panel tippy-target">
 		<div class="ui segment">
 			<form class="ui form" action="{{.Link}}/reviews/submit" method="post">
 			{{.CsrfTokenHtml}}
diff --git a/web_src/css/review.css b/web_src/css/review.css
index b58cc5a196..42267b4d2a 100644
--- a/web_src/css/review.css
+++ b/web_src/css/review.css
@@ -214,6 +214,10 @@ a.blob-excerpt:hover {
   color: var(--color-primary-contrast);
 }
 
+.review-box-panel .ui.segment {
+  border: none;
+}
+
 /* See the comment of createCommentEasyMDE() for the review editor */
 /* EasyMDE's options can not handle minHeight & maxHeight together correctly, we have to set minHeight in JS code */
 .review-box-panel .CodeMirror-scroll {
@@ -249,14 +253,6 @@ a.blob-excerpt:hover {
   position: relative;
 }
 
-.review-box-panel {
-  position: absolute;
-  min-width: max-content;
-  top: 45px;
-  right: -5px;
-  z-index: 2;
-}
-
 #review-box .review-comments-counter {
   background-color: var(--color-primary-light-4);
   color: var(--color-primary-contrast);
diff --git a/web_src/js/features/repo-issue.js b/web_src/js/features/repo-issue.js
index 4163fb120e..2b283b3c24 100644
--- a/web_src/js/features/repo-issue.js
+++ b/web_src/js/features/repo-issue.js
@@ -4,7 +4,7 @@ import {attachTribute} from './tribute.js';
 import {createCommentEasyMDE, getAttachedEasyMDE} from './comp/EasyMDE.js';
 import {initEasyMDEImagePaste} from './comp/ImagePaste.js';
 import {initCompMarkupContentPreviewTab} from './comp/MarkupContentPreview.js';
-import {initTooltip, showTemporaryTooltip} from '../modules/tippy.js';
+import {initTooltip, showTemporaryTooltip, createTippy} from '../modules/tippy.js';
 import {hideElem, showElem, toggleElem} from '../utils/dom.js';
 
 const {appSubUrl, csrfToken} = window.config;
@@ -491,12 +491,23 @@ export function initRepoPullRequestReview() {
     return;
   }
 
-  $('.js-btn-review').on('click', function (e) {
+  const $reviewBtn = $('.js-btn-review');
+  const $panel = $reviewBtn.parent().find('.review-box-panel');
+  const $closeBtn = $panel.find('.close');
+
+  const tippy = createTippy($reviewBtn[0], {
+    content: $panel[0],
+    placement: 'bottom',
+    trigger: 'click',
+    role: 'menu',
+    maxWidth: 'none',
+    interactive: true,
+    hideOnClick: true,
+  });
+
+  $closeBtn.on('click', (e) => {
     e.preventDefault();
-    toggleElem($(this).parent().find('.review-box-panel'));
-  }).parent().find('.review-box-panel .close').on('click', function (e) {
-    e.preventDefault();
-    hideElem($(this).closest('.review-box-panel'));
+    tippy.hide();
   });
 
   $(document).on('click', 'a.add-code-comment', async function (e) {