Просмотр исходного кода

fix(themes): replace #load_more loading-state GIF with a CSS spinner (#8804)

* fix(themes): replace #load_more loading-state GIF with a CSS spinner

In its `.loading` state, the "Load more" button kept its `.btn` frame and the spinner inside was hard to see or invisible across themes. Replaces the GIF with a base-theme CSS spinner inheriting `currentColor`, drops the button frame, respects `prefers-reduced-motion`, and renders crisply at any DPI. Per-theme `#load_more.loading` overrides in Nord, Flat, Mapco, Ansum and Swage become redundant and are removed; a now-redundant `font-size: 0` rule in `base.css` is also dropped.

* fix(themes): use border-rotation spinner for older-browser compat

Replaces conic-gradient + mask + aspect-ratio (Firefox 83+, Safari 15.4+) with border + rotate, supported in Gecko since Firefox 16 (2012) and Blink/WebKit since 2015. Visual difference: a ring with a rotating gap instead of a tapered arc. currentColor inheritance and prefers-reduced-motion handling are preserved.

* fix(themes): regenerate RTL spinner stylesheet

rtlcss flips border-right-color to border-left-color for RTL; the manual port of the spinner block missed it. Regenerated via npm run rtlcss.

Reworked the spinner with border + rotate instead of conic-gradient + mask + aspect-ratio. 

<img width="35" height="36" alt="Screenshot 2026-05-11 at 11 05 43" src="https://github.com/user-attachments/assets/e065efc9-9d6c-4369-8390-f0e89db81952" />

Oldest browser versions still supported: Firefox 16 (2012), SeaMonkey 2.13 (2012), Chrome 43 (2015), Safari 9 (2015), Edge 12 (2015). Below those, `@keyframes` and `animation` would need `-webkit-` fallbacks.

Verified now working in SeaMonkey 2.53.23. Couldn't test feed clicks or page reload there because login itself hits a separate cookie issue.
---------

Co-authored-by: Bjørn A. Andersen <polybjorn@users.noreply.github.com>
polybjorn 1 неделя назад
Родитель
Сommit
1ff27fea21

+ 0 - 5
p/themes/Ansum/_components.css

@@ -201,11 +201,6 @@
 	}
 }
 
-#load_more.loading,
-#load_more.loading:hover {
-	background: url("loader.gif") center center no-repeat #34495e;
-}
-
 /*=== Boxes */
 .box {
 	background: var(--white);

+ 0 - 5
p/themes/Ansum/_components.rtl.css

@@ -201,11 +201,6 @@
 	}
 }
 
-#load_more.loading,
-#load_more.loading:hover {
-	background: url("loader.gif") center center no-repeat #34495e;
-}
-
 /*=== Boxes */
 .box {
 	background: var(--white);

+ 0 - 5
p/themes/Flat/flat.css

@@ -417,11 +417,6 @@ th {
 	color: #000;
 }
 
-#load_more.loading,
-#load_more.loading:hover {
-	background: url("loader.gif") center center no-repeat #34495e;
-}
-
 /*=== Boxes */
 .box {
 	border: 1px solid #ddd;

+ 0 - 5
p/themes/Flat/flat.rtl.css

@@ -417,11 +417,6 @@ th {
 	color: #000;
 }
 
-#load_more.loading,
-#load_more.loading:hover {
-	background: url("loader.gif") center center no-repeat #34495e;
-}
-
 /*=== Boxes */
 .box {
 	border: 1px solid #ddd;

+ 0 - 5
p/themes/Mapco/_components.css

@@ -189,11 +189,6 @@
 
 }
 
-#load_more.loading,
-#load_more.loading:hover {
-	background: url("loader.gif") center center no-repeat #34495e;
-}
-
 /*=== Boxes */
 .box {
 	background: var(--white);

+ 0 - 5
p/themes/Mapco/_components.rtl.css

@@ -189,11 +189,6 @@
 
 }
 
-#load_more.loading,
-#load_more.loading:hover {
-	background: url("loader.gif") center center no-repeat #34495e;
-}
-
 /*=== Boxes */
 .box {
 	background: var(--white);

+ 0 - 8
p/themes/Nord/nord.css

@@ -877,14 +877,6 @@ li.item.active {
 	margin: 0;
 }
 
-#load_more.loading {
-	background-color: var(--accent);
-}
-
-#load_more.loading:hover {
-	background-color: var(--highlight);
-}
-
 /*=== Notification and actualize notification */
 .notification {
 	background: var(--dropdown-bg);

+ 0 - 8
p/themes/Nord/nord.rtl.css

@@ -877,14 +877,6 @@ li.item.active {
 	margin: 0;
 }
 
-#load_more.loading {
-	background-color: var(--accent);
-}
-
-#load_more.loading:hover {
-	background-color: var(--highlight);
-}
-
 /*=== Notification and actualize notification */
 .notification {
 	background: var(--dropdown-bg);

+ 0 - 6
p/themes/Swage/swage.css

@@ -564,12 +564,6 @@ li.item.separator {
 	}
 }
 
-#load_more.loading,
-#load_more.loading:hover {
-	background: url(loader.gif) center center no-repeat var(--color-background-aside);
-}
-
-
 .content {
 	padding: 20px 10px;
 

+ 0 - 6
p/themes/Swage/swage.rtl.css

@@ -564,12 +564,6 @@ li.item.separator {
 	}
 }
 
-#load_more.loading,
-#load_more.loading:hover {
-	background: url(loader.gif) center center no-repeat var(--color-background-aside);
-}
-
-
 .content {
 	padding: 20px 10px;
 

+ 0 - 5
p/themes/base-theme/base.css

@@ -300,11 +300,6 @@ th {
 .pagination:last-child .item {
 }
 
-#load_more.loading,
-#load_more.loading:hover {
-	font-size: 0;
-}
-
 /*=== Boxes */
 .box {
 }

+ 0 - 5
p/themes/base-theme/base.rtl.css

@@ -300,11 +300,6 @@ th {
 .pagination:last-child .item {
 }
 
-#load_more.loading,
-#load_more.loading:hover {
-	font-size: 0;
-}
-
 /*=== Boxes */
 .box {
 }

+ 26 - 2
p/themes/base-theme/frss.css

@@ -1970,11 +1970,35 @@ a.website:hover .favicon {
 
 #load_more.loading,
 #load_more.loading:hover {
-	padding: 10px 20px;
-	background: var(--frss-loading-image) center center no-repeat var(--frss-background-color);
+	position: relative;
+	min-width: 40px;
+	background: none;
+	border-color: transparent;
 	font-size: 0;
 }
 
+#load_more.loading::after {
+	content: "";
+	position: absolute;
+	top: calc(50% - 12px);
+	left: calc(50% - 12px);
+	width: 24px;
+	height: 24px;
+	border: 3px solid currentColor;
+	border-right-color: transparent;
+	border-radius: 50%;
+	opacity: 0.7;
+	animation: frss-spin 1s linear infinite;
+}
+
+@keyframes frss-spin {
+	to { transform: rotate(360deg); }
+}
+
+@media (prefers-reduced-motion: reduce) {
+	#load_more.loading::after { animation: none; }
+}
+
 .loading {
 	background: var(--frss-loading-image) center center no-repeat;
 	font-size: 0;

+ 26 - 2
p/themes/base-theme/frss.rtl.css

@@ -1970,11 +1970,35 @@ a.website:hover .favicon {
 
 #load_more.loading,
 #load_more.loading:hover {
-	padding: 10px 20px;
-	background: var(--frss-loading-image) center center no-repeat var(--frss-background-color);
+	position: relative;
+	min-width: 40px;
+	background: none;
+	border-color: transparent;
 	font-size: 0;
 }
 
+#load_more.loading::after {
+	content: "";
+	position: absolute;
+	top: calc(50% - 12px);
+	right: calc(50% - 12px);
+	width: 24px;
+	height: 24px;
+	border: 3px solid currentColor;
+	border-left-color: transparent;
+	border-radius: 50%;
+	opacity: 0.7;
+	animation: frss-spin 1s linear infinite;
+}
+
+@keyframes frss-spin {
+	to { transform: rotate(-360deg); }
+}
+
+@media (prefers-reduced-motion: reduce) {
+	#load_more.loading::after { animation: none; }
+}
+
 .loading {
 	background: var(--frss-loading-image) center center no-repeat;
 	font-size: 0;