diff --git a/models/avatar.go b/models/avatar.go
index ac260fbd93..166ca337ca 100644
--- a/models/avatar.go
+++ b/models/avatar.go
@@ -40,6 +40,12 @@ func DefaultAvatarLink() string {
 // determined by the avatar-hosting service.
 const DefaultAvatarSize = -1
 
+// DefaultAvatarPixelSize is the default size in pixels of a rendered avatar
+const DefaultAvatarPixelSize = 28
+
+// AvatarRenderedSizeFactor is the factor by which the default size is increased for finer rendering
+const AvatarRenderedSizeFactor = 2
+
 // HashEmail hashes email address to MD5 string.
 // https://en.gravatar.com/site/implement/hash/
 func HashEmail(email string) string {
diff --git a/modules/repository/commits.go b/modules/repository/commits.go
index fd8b8d927a..6b67c2c262 100644
--- a/modules/repository/commits.go
+++ b/modules/repository/commits.go
@@ -118,12 +118,14 @@ func (pc *PushCommits) AvatarLink(email string) string {
 		return avatar
 	}
 
+	size := models.DefaultAvatarPixelSize * models.AvatarRenderedSizeFactor
+
 	u, ok := pc.emailUsers[email]
 	if !ok {
 		var err error
 		u, err = models.GetUserByEmail(email)
 		if err != nil {
-			pc.avatars[email] = models.HashedAvatarLink(email)
+			pc.avatars[email] = models.SizedAvatarLink(email, size)
 			if !models.IsErrUserNotExist(err) {
 				log.Error("GetUserByEmail: %v", err)
 				return ""
@@ -133,7 +135,7 @@ func (pc *PushCommits) AvatarLink(email string) string {
 		}
 	}
 	if u != nil {
-		pc.avatars[email] = u.RelAvatarLink()
+		pc.avatars[email] = u.RealSizedAvatarLink(size)
 	}
 
 	return pc.avatars[email]
diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go
index cb00e19c2e..16677fe8a6 100644
--- a/modules/repository/commits_test.go
+++ b/modules/repository/commits_test.go
@@ -112,11 +112,13 @@ func TestPushCommits_AvatarLink(t *testing.T) {
 	pushCommits.Len = len(pushCommits.Commits)
 
 	assert.Equal(t,
-		"/user/avatar/user2/-1",
+		"https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon&s=56",
 		pushCommits.AvatarLink("user2@example.com"))
 
 	assert.Equal(t,
-		"/avatar/"+fmt.Sprintf("%x", md5.Sum([]byte("nonexistent@example.com"))),
+		"https://secure.gravatar.com/avatar/"+
+			fmt.Sprintf("%x", md5.Sum([]byte("nonexistent@example.com")))+
+			"?d=identicon&s=56",
 		pushCommits.AvatarLink("nonexistent@example.com"))
 }
 
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 0b5ae0f013..f7c10c3698 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -340,6 +340,7 @@ func NewFuncMap() []template.FuncMap {
 		},
 		"svg":           SVG,
 		"avatar":        Avatar,
+		"avatarHTML":    AvatarHTML,
 		"avatarByEmail": AvatarByEmail,
 		"repoAvatar":    RepoAvatar,
 		"SortArrow": func(normSort, revSort, urlSort string, isDefault bool) template.HTML {
@@ -519,7 +520,8 @@ func parseOthers(defaultSize int, defaultClass string, others ...interface{}) (i
 	return size, class
 }
 
-func avatarHTML(src string, size int, class string, name string) template.HTML {
+// AvatarHTML creates the HTML for an avatar
+func AvatarHTML(src string, size int, class string, name string) template.HTML {
 	sizeStr := fmt.Sprintf(`%d`, size)
 
 	if name == "" {
@@ -548,33 +550,33 @@ func SVG(icon string, others ...interface{}) template.HTML {
 
 // Avatar renders user avatars. args: user, size (int), class (string)
 func Avatar(user *models.User, others ...interface{}) template.HTML {
-	size, class := parseOthers(28, "ui avatar image", others...)
+	size, class := parseOthers(models.DefaultAvatarPixelSize, "ui avatar image", others...)
 
-	src := user.RealSizedAvatarLink(size * 2) // request double size for finer rendering
+	src := user.RealSizedAvatarLink(size * models.AvatarRenderedSizeFactor)
 	if src != "" {
-		return avatarHTML(src, size, class, user.DisplayName())
+		return AvatarHTML(src, size, class, user.DisplayName())
 	}
 	return template.HTML("")
 }
 
 // RepoAvatar renders repo avatars. args: repo, size(int), class (string)
 func RepoAvatar(repo *models.Repository, others ...interface{}) template.HTML {
-	size, class := parseOthers(28, "ui avatar image", others...)
+	size, class := parseOthers(models.DefaultAvatarPixelSize, "ui avatar image", others...)
 
 	src := repo.RelAvatarLink()
 	if src != "" {
-		return avatarHTML(src, size, class, repo.FullName())
+		return AvatarHTML(src, size, class, repo.FullName())
 	}
 	return template.HTML("")
 }
 
 // AvatarByEmail renders avatars by email address. args: email, name, size (int), class (string)
 func AvatarByEmail(email string, name string, others ...interface{}) template.HTML {
-	size, class := parseOthers(28, "ui avatar image", others...)
-	src := models.SizedAvatarLink(email, size*2) // request double size for finer rendering
+	size, class := parseOthers(models.DefaultAvatarPixelSize, "ui avatar image", others...)
+	src := models.SizedAvatarLink(email, size*models.AvatarRenderedSizeFactor)
 
 	if src != "" {
-		return avatarHTML(src, size, class, name)
+		return AvatarHTML(src, size, class, name)
 	}
 
 	return template.HTML("")
diff --git a/templates/admin/hook_new.tmpl b/templates/admin/hook_new.tmpl
index 8eeb0e5264..dabd568f93 100644
--- a/templates/admin/hook_new.tmpl
+++ b/templates/admin/hook_new.tmpl
@@ -11,23 +11,23 @@
 			{{end}}
 			<div class="ui right">
 				{{if eq .HookType "gitea"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/gitea-sm.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/gitea-sm.png">
 				{{else if eq .HookType "gogs"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/gogs.ico">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/gogs.ico">
 				{{else if eq .HookType "slack"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/slack.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/slack.png">
 				{{else if eq .HookType "discord"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/discord.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/discord.png">
 				{{else if eq .HookType "dingtalk"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/dingtalk.ico">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/dingtalk.ico">
 				{{else if eq .HookType "telegram"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/telegram.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/telegram.png">
 				{{else if eq .HookType "msteams"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/msteams.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/msteams.png">
 				{{else if eq .HookType "feishu"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/feishu.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/feishu.png">
 				{{else if eq .HookType "matrix"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/matrix.svg">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/matrix.svg">
 				{{end}}
 			</div>
 		</h4>
diff --git a/templates/org/settings/hook_new.tmpl b/templates/org/settings/hook_new.tmpl
index 96769c7446..2fdf2662d6 100644
--- a/templates/org/settings/hook_new.tmpl
+++ b/templates/org/settings/hook_new.tmpl
@@ -10,23 +10,23 @@
 					{{if .PageIsSettingsHooksNew}}{{.i18n.Tr "repo.settings.add_webhook"}}{{else}}{{.i18n.Tr "repo.settings.update_webhook"}}{{end}}
 					<div class="ui right">
 						{{if eq .HookType "gitea"}}
-							<img class="img-13" src="{{StaticUrlPrefix}}/img/gitea-sm.png">
+							<img width="26" height="26" src="{{StaticUrlPrefix}}/img/gitea-sm.png">
 						{{else if eq .HookType "gogs"}}
-							<img class="img-13" src="{{StaticUrlPrefix}}/img/gogs.ico">
+							<img width="26" height="26" src="{{StaticUrlPrefix}}/img/gogs.ico">
 						{{else if eq .HookType "slack"}}
-							<img class="img-13" src="{{StaticUrlPrefix}}/img/slack.png">
+							<img width="26" height="26" src="{{StaticUrlPrefix}}/img/slack.png">
 						{{else if eq .HookType "discord"}}
-							<img class="img-13" src="{{StaticUrlPrefix}}/img/discord.png">
+							<img width="26" height="26" src="{{StaticUrlPrefix}}/img/discord.png">
 						{{else if eq .HookType "dingtalk"}}
-							<img class="img-13" src="{{StaticUrlPrefix}}/img/dingtalk.png">
+							<img width="26" height="26" src="{{StaticUrlPrefix}}/img/dingtalk.png">
 						{{else if eq .HookType "telegram"}}
-							<img class="img-13" src="{{StaticUrlPrefix}}/img/telegram.png">
+							<img width="26" height="26" src="{{StaticUrlPrefix}}/img/telegram.png">
 						{{else if eq .HookType "msteams"}}
-							<img class="img-13" src="{{StaticUrlPrefix}}/img/msteams.png">
+							<img width="26" height="26" src="{{StaticUrlPrefix}}/img/msteams.png">
 						{{else if eq .HookType "feishu"}}
-							<img class="img-13" src="{{StaticUrlPrefix}}/img/feishu.png">
+							<img width="26" height="26" src="{{StaticUrlPrefix}}/img/feishu.png">
 						{{else if eq .HookType "matrix"}}
-							<img class="img-13" src="{{StaticUrlPrefix}}/img/matrix.svg">
+							<img width="26" height="26" src="{{StaticUrlPrefix}}/img/matrix.svg">
 						{{end}}
 					</div>
 				</h4>
diff --git a/templates/repo/release/list.tmpl b/templates/repo/release/list.tmpl
index 70a614ff72..780a75ad89 100644
--- a/templates/repo/release/list.tmpl
+++ b/templates/repo/release/list.tmpl
@@ -90,7 +90,7 @@
 							<p class="text grey">
 								{{ if gt .Publisher.ID 0 }}
 								<span class="author">
-									{{avatar .Publisher 28 "img-10"}}
+									{{avatar .Publisher 20}}
 									<a href="{{AppSubUrl}}/{{.Publisher.Name}}">{{.Publisher.Name}}</a>
 								</span>
 								{{ end }}
@@ -117,7 +117,7 @@
 								{{if .OriginalAuthor}}
 									{{svg "octicon-mark-github" 16 "mr-2"}}{{.OriginalAuthor}}
 								{{else if .Publisher}}
-									{{avatar .Publisher 28 "img-10"}}
+									{{avatar .Publisher 20}}
 									<a href="{{AppSubUrl}}/{{.Publisher.Name}}">{{.Publisher.GetDisplayName}}</a>
 								{{else}}
 									Ghost
diff --git a/templates/repo/settings/webhook/list.tmpl b/templates/repo/settings/webhook/list.tmpl
index 29994d8197..47ed37cc33 100644
--- a/templates/repo/settings/webhook/list.tmpl
+++ b/templates/repo/settings/webhook/list.tmpl
@@ -6,31 +6,31 @@
 			<div class="ui blue tiny button">{{.i18n.Tr "repo.settings.add_webhook"}}</div>
 			<div class="menu">
 				<a class="item" href="{{.BaseLink}}/gitea/new">
-					<img class="img-10" src="{{StaticUrlPrefix}}/img/gitea-sm.png">Gitea
+					<img width="20" height="20" src="{{StaticUrlPrefix}}/img/gitea-sm.png">Gitea
 				</a>
 				<a class="item" href="{{.BaseLink}}/gogs/new">
-					<img class="img-10" src="{{StaticUrlPrefix}}/img/gogs.ico">Gogs
+					<img width="20" height="20" src="{{StaticUrlPrefix}}/img/gogs.ico">Gogs
 				</a>
 				<a class="item" href="{{.BaseLink}}/slack/new">
-					<img class="img-10" src="{{StaticUrlPrefix}}/img/slack.png">Slack
+					<img width="20" height="20" src="{{StaticUrlPrefix}}/img/slack.png">Slack
 				</a>
 				<a class="item" href="{{.BaseLink}}/discord/new">
-					<img class="img-10" src="{{StaticUrlPrefix}}/img/discord.png">Discord
+					<img width="20" height="20" src="{{StaticUrlPrefix}}/img/discord.png">Discord
 				</a>
 				<a class="item" href="{{.BaseLink}}/dingtalk/new">
-					<img class="img-10" src="{{StaticUrlPrefix}}/img/dingtalk.ico">Dingtalk
+					<img width="20" height="20" src="{{StaticUrlPrefix}}/img/dingtalk.ico">Dingtalk
 				</a>
 				<a class="item" href="{{.BaseLink}}/telegram/new">
-					<img class="img-10" src="{{StaticUrlPrefix}}/img/telegram.png">Telegram
+					<img width="20" height="20" src="{{StaticUrlPrefix}}/img/telegram.png">Telegram
 				</a>
 				<a class="item" href="{{.BaseLink}}/msteams/new">
-					<img class="img-10" src="{{StaticUrlPrefix}}/img/msteams.png">Microsoft Teams
+					<img width="20" height="20" src="{{StaticUrlPrefix}}/img/msteams.png">Microsoft Teams
 				</a>
 				<a class="item" href="{{.BaseLink}}/feishu/new">
-					<img class="img-10" src="{{StaticUrlPrefix}}/img/feishu.png">Feishu
+					<img width="20" height="20" src="{{StaticUrlPrefix}}/img/feishu.png">Feishu
 				</a>
 				<a class="item" href="{{.BaseLink}}/matrix/new">
-                	<img class="img-10" src="{{StaticUrlPrefix}}/img/matrix.svg">Matrix
+					<img width="20" height="20" src="{{StaticUrlPrefix}}/img/matrix.svg">Matrix
 				</a>
 			</div>
 		</div>
diff --git a/templates/repo/settings/webhook/new.tmpl b/templates/repo/settings/webhook/new.tmpl
index fc78db8648..ac5d1886b2 100644
--- a/templates/repo/settings/webhook/new.tmpl
+++ b/templates/repo/settings/webhook/new.tmpl
@@ -8,23 +8,23 @@
 			{{if .PageIsSettingsHooksNew}}{{.i18n.Tr "repo.settings.add_webhook"}}{{else}}{{.i18n.Tr "repo.settings.update_webhook"}}{{end}}
 			<div class="ui right">
 				{{if eq .HookType "gitea"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/gitea-sm.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/gitea-sm.png">
 				{{else if eq .HookType "gogs"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/gogs.ico">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/gogs.ico">
 				{{else if eq .HookType "slack"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/slack.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/slack.png">
 				{{else if eq .HookType "discord"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/discord.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/discord.png">
 				{{else if eq .HookType "dingtalk"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/dingtalk.ico">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/dingtalk.ico">
 				{{else if eq .HookType "telegram"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/telegram.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/telegram.png">
 				{{else if eq .HookType "msteams"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/msteams.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/msteams.png">
 				{{else if eq .HookType "feishu"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/feishu.png">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/feishu.png">
 				{{else if eq .HookType "matrix"}}
-					<img class="img-13" src="{{StaticUrlPrefix}}/img/matrix.svg">
+					<img width="26" height="26" src="{{StaticUrlPrefix}}/img/matrix.svg">
 				{{end}}
 			</div>
 		</h4>
diff --git a/templates/repo/view_list.tmpl b/templates/repo/view_list.tmpl
index 651747f20a..3266a813e3 100644
--- a/templates/repo/view_list.tmpl
+++ b/templates/repo/view_list.tmpl
@@ -3,7 +3,7 @@
 		<tr class="commit-list">
 			<th colspan="2">
 				{{if .LatestCommitUser}}
-					{{avatar .LatestCommitUser 28 "img-12"}}
+					{{avatar .LatestCommitUser 24}}
 					{{if .LatestCommitUser.FullName}}
 						<a href="{{AppSubUrl}}/{{.LatestCommitUser.Name}}"><strong>{{.LatestCommitUser.FullName}}</strong></a>
 					{{else}}
@@ -11,7 +11,7 @@
 					{{end}}
 				{{else}}
 					{{if .LatestCommit.Author}}
-						{{avatarByEmail .LatestCommit.Author.Email .LatestCommit.Author.Name 28 "img-12"}}
+						{{avatarByEmail .LatestCommit.Author.Email .LatestCommit.Author.Name 24}}
 						<strong>{{.LatestCommit.Author.Name}}</strong>
 					{{end}}
 				{{end}}
diff --git a/templates/user/dashboard/feeds.tmpl b/templates/user/dashboard/feeds.tmpl
index 76c751de8a..0d9f7de5a7 100644
--- a/templates/user/dashboard/feeds.tmpl
+++ b/templates/user/dashboard/feeds.tmpl
@@ -85,7 +85,7 @@
 									{{range $push.Commits}}
 										{{ $commitLink := printf "%s/commit/%s" $repoLink .Sha1}}
 										<li>
-											{{avatarByEmail .AuthorEmail .AuthorName 28 "img-8 mr-2"}}
+											{{avatarHTML ($push.AvatarLink .AuthorEmail) 16 "mr-2" .AuthorName}}
 											<a class="commit-id mr-2" href="{{$commitLink}}">{{ShortSha .Sha1}}</a>
 											<span class="text truncate light grey">
 												{{RenderCommitMessage .Message $repoLink $.ComposeMetas}}
diff --git a/web_src/less/_base.less b/web_src/less/_base.less
index 81c6a310f5..0e555daf9f 100644
--- a/web_src/less/_base.less
+++ b/web_src/less/_base.less
@@ -312,6 +312,12 @@ a.muted:hover,
   font-weight: normal;
 }
 
+/* fix misaligned images in webhook dropdown */
+.ui.dropdown .menu > .item > img {
+  margin-top: -.25rem;
+  margin-bottom: -.25rem;
+}
+
 .ui.selection.dropdown .menu > .item {
   border-color: var(--color-secondary);
 }
@@ -1101,16 +1107,6 @@ footer {
   text-align: center;
 }
 
-.generate-img(16);
-.generate-img(@n, @i: 1) when (@i =< @n) {
-  .img-@{i} {
-    width: (2px * @i) !important;
-    height: (2px * @i) !important;
-  }
-
-  .generate-img(@n, (@i + 1));
-}
-
 // Conditional display
 @media @mediaMdAndUp {
   .mobile-only,
@@ -1660,6 +1656,11 @@ a.ui.basic.label:hover {
   visibility: hidden;
 }
 
+/* prevent stacking context issue on webhook dropdown */
+.ui.segment {
+  position: static;
+}
+
 .ui.segment,
 .ui.segments,
 .ui.attached.segment {
diff --git a/web_src/less/helpers.less b/web_src/less/helpers.less
index 7e299339f8..c611076f48 100644
--- a/web_src/less/helpers.less
+++ b/web_src/less/helpers.less
@@ -22,7 +22,7 @@
 }
 
 .full-screen-width { width: 100vw !important; }
-.full-screen-height { height: 100vw !important; }
+.full-screen-height { height: 100vh !important; }
 
 .rounded { border-radius: var(--border-radius) !important; }
 .rounded-top { border-radius: var(--border-radius) var(--border-radius) 0 0 !important; }