diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go
index 3dd7725c2..5c378fe9d 100644
--- a/routers/web/repo/issue_content_history.go
+++ b/routers/web/repo/issue_content_history.go
@@ -11,7 +11,6 @@ import (
 
 	"code.gitea.io/gitea/models/avatars"
 	issues_model "code.gitea.io/gitea/models/issues"
-	"code.gitea.io/gitea/models/unit"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
@@ -91,11 +90,16 @@ func GetContentHistoryList(ctx *context.Context) {
 // Admins or owners can always delete history revisions. Normal users can only delete own history revisions.
 func canSoftDeleteContentHistory(ctx *context.Context, issue *issues_model.Issue, comment *issues_model.Comment,
 	history *issues_model.ContentHistory,
-) bool {
-	canSoftDelete := false
-	if ctx.Repo.IsOwner() {
+) (canSoftDelete bool) {
+	// CanWrite means the doer can manage the issue/PR list
+	if ctx.Repo.IsOwner() || ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) {
 		canSoftDelete = true
-	} else if ctx.Repo.CanWrite(unit.TypeIssues) {
+	} else {
+		// for read-only users, they could still post issues or comments,
+		// they should be able to delete the history related to their own issue/comment, a case is:
+		// 1. the user posts some sensitive data
+		// 2. then the repo owner edits the post but didn't remove the sensitive data
+		// 3. the poster wants to delete the edited history revision
 		if comment == nil {
 			// the issue poster or the history poster can soft-delete
 			canSoftDelete = ctx.Doer.ID == issue.PosterID || ctx.Doer.ID == history.PosterID
diff --git a/web_src/css/modules/modal.css b/web_src/css/modules/modal.css
index 96bc8be89..54a4ef81c 100644
--- a/web_src/css/modules/modal.css
+++ b/web_src/css/modules/modal.css
@@ -3,13 +3,18 @@
   width: fit-content;
 }
 
-.ui.modal.g-modal-confirm > .inside.close {
+.ui.modal.g-modal-confirm > .inside.close.icon {
   padding: 0;
   width: 1em;
   height: 1em;
   top: 1.2em;
 }
 
+.ui.modal > .close.icon[height="16"] {
+  top: 0.7em; /* fomantic uses absolute layout, so if we have special icon size, it needs this trick to align vertically */
+  color: var(--color-text-dark);
+}
+
 .ui.modal > .header {
   /* can't use display:flex, because some headers have space-separated elements, eg: delete branch modal */
   color: var(--color-text-dark);
diff --git a/web_src/css/repo.css b/web_src/css/repo.css
index b7b14f740..8e751ef88 100644
--- a/web_src/css/repo.css
+++ b/web_src/css/repo.css
@@ -2578,12 +2578,14 @@ tbody.commit-list {
 
 .comment-diff-data {
   background: var(--color-code-bg);
+  min-height: 12em;
   max-height: calc(100vh - 10.5rem);
   overflow-y: auto;
 }
 
 .comment-diff-data pre {
   line-height: 18px;
+  margin: 1em;
   white-space: pre-wrap;
   word-break: break-all;
   overflow-wrap: break-word;
diff --git a/web_src/js/features/repo-issue-content.js b/web_src/js/features/repo-issue-content.js
index 3ada166c5..783264168 100644
--- a/web_src/js/features/repo-issue-content.js
+++ b/web_src/js/features/repo-issue-content.js
@@ -17,14 +17,15 @@ function showContentHistoryDetail(issueBaseUrl, commentId, historyId, itemTitleH
   ${svg('octicon-x', 16, 'close icon inside')}
   <div class="header gt-df gt-ac gt-sb">
     <div>${itemTitleHtml}</div>
-    <div class="ui dropdown dialog-header-options gt-df gt-ac gt-mr-5 gt-hidden">
-      ${i18nTextOptions}${svg('octicon-triangle-down', 14, 'dropdown icon')}
+    <div class="ui dropdown dialog-header-options gt-mr-5 gt-hidden">
+      ${i18nTextOptions}
+      ${svg('octicon-triangle-down', 14, 'dropdown icon')}
       <div class="menu">
         <div class="item red text" data-option-item="delete">${i18nTextDeleteFromHistory}</div>
       </div>
     </div>
   </div>
-  <div class="comment-diff-data gt-text-left gt-p-3 is-loading"></div>
+  <div class="comment-diff-data is-loading"></div>
 </div>`);
   $dialog.appendTo($('body'));
   $dialog.find('.dialog-header-options').dropdown({