diff --git a/modules/markup/markdown/color_util.go b/modules/markup/markdown/color_util.go
new file mode 100644
index 0000000000..355fef3fc0
--- /dev/null
+++ b/modules/markup/markdown/color_util.go
@@ -0,0 +1,19 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package markdown
+
+import "regexp"
+
+var (
+	hexRGB = regexp.MustCompile(`^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$`)
+	hsl    = regexp.MustCompile(`^hsl\([ ]*([012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%\)$`)
+	hsla   = regexp.MustCompile(`^hsla\(([ ]*[012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%,[ ]*(1|1\.0|0|(0\.[0-9]+))\)$`)
+	rgb    = regexp.MustCompile(`^rgb\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){2}([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))))\)$`)
+	rgba   = regexp.MustCompile(`^rgba\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){3}[ ]*(1(\.0)?|0|(0\.[0-9]+))\)$`)
+)
+
+// matchColor return if color is in the form of hex RGB, HSL(A) or RGB(A).
+func matchColor(color string) bool {
+	return hexRGB.MatchString(color) || rgb.MatchString(color) || rgba.MatchString(color) || hsl.MatchString(color) || hsla.MatchString(color)
+}
diff --git a/modules/markup/markdown/color_util_test.go b/modules/markup/markdown/color_util_test.go
new file mode 100644
index 0000000000..c6e0555a35
--- /dev/null
+++ b/modules/markup/markdown/color_util_test.go
@@ -0,0 +1,50 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package markdown
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestMatchColor(t *testing.T) {
+	testCases := []struct {
+		input    string
+		expected bool
+	}{
+		{"#ddeeffa0", true},
+		{"#ddeefe", true},
+		{"#abcdef", true},
+		{"#abcdeg", false},
+		{"#abcdefg0", false},
+		{"black", false},
+		{"violet", false},
+		{"rgb(255, 255, 255)", true},
+		{"rgb(0, 0, 0)", true},
+		{"rgb(256, 0, 0)", false},
+		{"rgb(0, 256, 0)", false},
+		{"rgb(0, 0, 256)", false},
+		{"rgb(0, 0, 0, 1)", false},
+		{"rgba(0, 0, 0)", false},
+		{"rgba(0, 255, 0, 1)", true},
+		{"rgba(32, 255, 12, 0.55)", true},
+		{"rgba(32, 256, 12, 0.55)", false},
+		{"hsl(0, 0%, 0%)", true},
+		{"hsl(360, 100%, 100%)", true},
+		{"hsl(361, 100%, 50%)", false},
+		{"hsl(360, 101%, 50%)", false},
+		{"hsl(360, 100%, 101%)", false},
+		{"hsl(0, 0%, 0%, 0)", false},
+		{"hsla(0, 0%, 0%)", false},
+		{"hsla(0, 0%, 0%, 0)", true},
+		{"hsla(0, 0%, 0%, 1)", true},
+		{"hsla(0, 0%, 0%, 0.5)", true},
+		{"hsla(0, 0%, 0%, 1.5)", false},
+	}
+	for _, testCase := range testCases {
+		actual := matchColor(testCase.input)
+		assert.Equal(t, testCase.expected, actual)
+	}
+}
diff --git a/modules/markup/markdown/goldmark.go b/modules/markup/markdown/goldmark.go
index 7ada8b5548..5a481a31fd 100644
--- a/modules/markup/markdown/goldmark.go
+++ b/modules/markup/markdown/goldmark.go
@@ -16,7 +16,6 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	giteautil "code.gitea.io/gitea/modules/util"
 
-	"github.com/microcosm-cc/bluemonday/css"
 	"github.com/yuin/goldmark/ast"
 	east "github.com/yuin/goldmark/extension/ast"
 	"github.com/yuin/goldmark/parser"
@@ -199,7 +198,7 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
 			}
 		case *ast.CodeSpan:
 			colorContent := n.Text(reader.Source())
-			if css.ColorHandler(strings.ToLower(string(colorContent))) {
+			if matchColor(strings.ToLower(string(colorContent))) {
 				v.AppendChild(v, NewColorPreview(colorContent))
 			}
 		}