diff --git a/modules/typesniffer/typesniffer.go b/modules/typesniffer/typesniffer.go
index c9fef953ce..5b215496b8 100644
--- a/modules/typesniffer/typesniffer.go
+++ b/modules/typesniffer/typesniffer.go
@@ -4,6 +4,7 @@
 package typesniffer
 
 import (
+	"bytes"
 	"fmt"
 	"io"
 	"net/http"
@@ -24,8 +25,9 @@ const (
 )
 
 var (
-	svgTagRegex      = regexp.MustCompile(`(?si)\A\s*(?:(<!--.*?-->|<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg[\s>\/]`)
-	svgTagInXMLRegex = regexp.MustCompile(`(?si)\A<\?xml\b.*?\?>\s*(?:(<!--.*?-->|<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg[\s>\/]`)
+	svgComment       = regexp.MustCompile(`(?s)<!--.*?-->`)
+	svgTagRegex      = regexp.MustCompile(`(?si)\A\s*(?:(<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg\b`)
+	svgTagInXMLRegex = regexp.MustCompile(`(?si)\A<\?xml\b.*?\?>\s*(?:(<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg\b`)
 )
 
 // SniffedType contains information about a blobs type.
@@ -91,10 +93,17 @@ func DetectContentType(data []byte) SniffedType {
 		data = data[:sniffLen]
 	}
 
-	if (strings.Contains(ct, "text/plain") || strings.Contains(ct, "text/html")) && svgTagRegex.Match(data) ||
-		strings.Contains(ct, "text/xml") && svgTagInXMLRegex.Match(data) {
-		// SVG is unsupported. https://github.com/golang/go/issues/15888
-		ct = SvgMimeType
+	// SVG is unsupported by http.DetectContentType, https://github.com/golang/go/issues/15888
+
+	detectByHTML := strings.Contains(ct, "text/plain") || strings.Contains(ct, "text/html")
+	detectByXML := strings.Contains(ct, "text/xml")
+	if detectByHTML || detectByXML {
+		dataProcessed := svgComment.ReplaceAll(data, nil)
+		dataProcessed = bytes.TrimSpace(dataProcessed)
+		if detectByHTML && svgTagRegex.Match(dataProcessed) ||
+			detectByXML && svgTagInXMLRegex.Match(dataProcessed) {
+			ct = SvgMimeType
+		}
 	}
 
 	return SniffedType{ct}
diff --git a/modules/typesniffer/typesniffer_test.go b/modules/typesniffer/typesniffer_test.go
index dbce94fc3b..2bafdffd14 100644
--- a/modules/typesniffer/typesniffer_test.go
+++ b/modules/typesniffer/typesniffer_test.go
@@ -28,7 +28,6 @@ func TestIsSvgImage(t *testing.T) {
 	assert.True(t, DetectContentType([]byte("<svg></svg>")).IsSvgImage())
 	assert.True(t, DetectContentType([]byte("    <svg></svg>")).IsSvgImage())
 	assert.True(t, DetectContentType([]byte(`<svg width="100"></svg>`)).IsSvgImage())
-	assert.True(t, DetectContentType([]byte("<svg/>")).IsSvgImage())
 	assert.True(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?><svg></svg>`)).IsSvgImage())
 	assert.True(t, DetectContentType([]byte(`<!-- Comment -->
 	<svg></svg>`)).IsSvgImage())
@@ -57,6 +56,10 @@ func TestIsSvgImage(t *testing.T) {
 	<!-- Multline
 	Comment -->
 	<svg></svg>`)).IsSvgImage())
+
+	// the DetectContentType should work for incomplete data, because only beginning bytes are used for detection
+	assert.True(t, DetectContentType([]byte(`<svg>....`)).IsSvgImage())
+
 	assert.False(t, DetectContentType([]byte{}).IsSvgImage())
 	assert.False(t, DetectContentType([]byte("svg")).IsSvgImage())
 	assert.False(t, DetectContentType([]byte("<svgfoo></svgfoo>")).IsSvgImage())
@@ -68,6 +71,26 @@ func TestIsSvgImage(t *testing.T) {
 	assert.False(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?>
 	<!-- <svg></svg> inside comment -->
 	<foo></foo>`)).IsSvgImage())
+
+	assert.False(t, DetectContentType([]byte(`
+<!-- comment1 -->
+<div>
+	<!-- comment2 -->
+	<svg></svg>
+</div>
+`)).IsSvgImage())
+
+	assert.False(t, DetectContentType([]byte(`
+<!-- comment1
+-->
+<div>
+	<!-- comment2
+-->
+	<svg></svg>
+</div>
+`)).IsSvgImage())
+	assert.False(t, DetectContentType([]byte(`<html><body><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg></svg></body></html>`)).IsSvgImage())
+	assert.False(t, DetectContentType([]byte(`<html><body><?xml version="1.0" encoding="UTF-8"?><svg></svg></body></html>`)).IsSvgImage())
 }
 
 func TestIsPDF(t *testing.T) {
diff --git a/web_src/js/features/imagediff.js b/web_src/js/features/imagediff.js
index 7a285f1f8d..a26b927c33 100644
--- a/web_src/js/features/imagediff.js
+++ b/web_src/js/features/imagediff.js
@@ -129,8 +129,8 @@ export function initImageDiff() {
         initOverlay(createContext($imageAfter[2], $imageBefore[2]));
       }
 
-      hideElem($container.find('> .loader'));
       $container.find('> .gt-hidden').removeClass('gt-hidden');
+      hideElem($container.find('.ui.loader'));
     }
 
     function initSideBySide(sizes) {
@@ -155,7 +155,7 @@ export function initImageDiff() {
         height: sizes.size1.height * factor
       });
       sizes.image1.parent().css({
-        margin: `${sizes.ratio[1] * factor + 15}px ${sizes.ratio[0] * factor}px ${sizes.ratio[1] * factor}px`,
+        margin: `10px auto`,
         width: sizes.size1.width * factor + 2,
         height: sizes.size1.height * factor + 2
       });
@@ -164,7 +164,7 @@ export function initImageDiff() {
         height: sizes.size2.height * factor
       });
       sizes.image2.parent().css({
-        margin: `${sizes.ratio[3] * factor}px ${sizes.ratio[2] * factor}px`,
+        margin: `10px auto`,
         width: sizes.size2.width * factor + 2,
         height: sizes.size2.height * factor + 2
       });
@@ -255,13 +255,12 @@ export function initImageDiff() {
         width: sizes.size2.width * factor + 2,
         height: sizes.size2.height * factor + 2
       });
+
+      // some inner elements are `position: absolute`, so the container's height must be large enough
+      // the "css(width, height)" is somewhat hacky and not easy to understand, it could be improved in the future
       sizes.image2.parent().parent().css({
         width: sizes.max.width * factor + 2,
-        height: sizes.max.height * factor + 2
-      });
-      $container.find('.onion-skin').css({
-        width: sizes.max.width * factor + 2,
-        height: sizes.max.height * factor + 4
+        height: sizes.max.height * factor + 2 + 20 /* extra height for inner "position: absolute" elements */,
       });
 
       const $range = $container.find("input[type='range']");
diff --git a/web_src/less/features/imagediff.less b/web_src/less/features/imagediff.less
index a9ba7f8c8f..07763c15e1 100644
--- a/web_src/less/features/imagediff.less
+++ b/web_src/less/features/imagediff.less
@@ -1,6 +1,6 @@
 .image-diff-container {
   text-align: center;
-  padding: 30px 0;
+  padding: 1em 0;
 
   img {
     border: 1px solid var(--color-primary-light-7);
@@ -22,6 +22,7 @@
       display: inline-block;
       line-height: 0;
       vertical-align: top;
+      margin: 0 1em;
 
       .side-header {
         font-weight: bold;
@@ -98,7 +99,7 @@
     }
 
     input {
-      width: 300px;
+      max-width: 300px;
     }
   }
 }