From 8ca99ec1144edee151ed1da4b09201c03010fadc Mon Sep 17 00:00:00 2001 From: polybjorn Date: Thu, 30 Apr 2026 06:15:35 +0000 Subject: [PATCH] fix(themes): restore radius on lone .group buttons in nav_menu (#8731) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #7405 Several themes inherit the same button-radius cascade bug: a single button inside a `.group` element ends up right-rounded only because the `.btn` matches both `:first-child` and `:last-child`, and the right-radius rule wins by source order. Visible on: - The **Update feeds** button (lone `.btn` in `#nav_menu_actualize`) - The **Toggle sidebar** button at narrow width (`#nav_menu_toggle_aside`) - The **Sorting** button (`.btn` inside a lone `.dropdown` in `#nav_menu_sort`) The fix uses targeted `:only-child` rules that give full radius to lone `.group` children, with selector form `.group > .btn:only-child, .group > .dropdown:only-child > .btn`. In **Dark** and **Origine**, the Sorting button also needs an explicit `border-left` restored on the dropdown branch. Origine's `.group .dropdown:last-child > .btn { border-left: none }` strips the left border from a lone dropdown's button. Dark inherits this strip rule via its `../Origine/origine.css` import, so the same fix is applied in both themes, each re-asserting the border in its own variable (`--border-color` for Origine, `--dark-border-color0` for Dark). The radius rule and the border-left re-assertion are kept as separate blocks so the border-left only applies to the dropdown case, not to lone `.btn` children. Themes affected directly: Alternative-Dark, Ansum, Dark, Flat, Mapco, Origine, Pafat. Dark-pink inherits via its `../Alternative-Dark/adark.css` import; Origine-compact inherits via its `../Origine/origine.css` import. The same restore-radius / restore-border approach was approved in #8711 for Nord's mark-read toggle. ### Out of scope The mark-read dropdown (`#nav_menu_read_all`) at narrow widths looks similar but is not fixed here. The dropdown is not a CSS `:only-child` of `.group` (its sibling `.read_all` button is still in the DOM, even when it visually wraps to a new row), so the rules in this PR do not match it. That case is handled in a separate upcoming PR with `@media` rules per theme. ### Screenshots #### Sorting button (visible-border theme) Before: origine visible-border original After: origine visible-border fixed #### Update feeds button (lone .btn case) Before: mapco lone btn original After: mapco lone btn fixed ### Notes - `.rtl.css` regenerated via `make rtl`. - `npm run stylelint` passes. - Tested locally on FreshRSS 1.28.2-dev across all affected themes. Co-authored-by: Bjørn A. Andersen --- p/themes/Alternative-Dark/adark.css | 5 +++++ p/themes/Alternative-Dark/adark.rtl.css | 5 +++++ p/themes/Ansum/_sidebar.css | 5 +++++ p/themes/Ansum/_sidebar.rtl.css | 5 +++++ p/themes/Dark/dark.css | 9 +++++++++ p/themes/Dark/dark.rtl.css | 9 +++++++++ p/themes/Flat/flat.css | 5 +++++ p/themes/Flat/flat.rtl.css | 5 +++++ p/themes/Mapco/_sidebar.css | 5 +++++ p/themes/Mapco/_sidebar.rtl.css | 5 +++++ p/themes/Origine/origine.css | 9 +++++++++ p/themes/Origine/origine.rtl.css | 9 +++++++++ p/themes/Pafat/pafat.css | 5 +++++ p/themes/Pafat/pafat.rtl.css | 5 +++++ 14 files changed, 86 insertions(+) diff --git a/p/themes/Alternative-Dark/adark.css b/p/themes/Alternative-Dark/adark.css index 98679f8f9..44ac98152 100644 --- a/p/themes/Alternative-Dark/adark.css +++ b/p/themes/Alternative-Dark/adark.css @@ -178,6 +178,11 @@ th { border-radius: 0 3px 3px 0; } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 3px; +} + .stick .btn + .btn, .group .btn + .btn, .stick .btn + input, diff --git a/p/themes/Alternative-Dark/adark.rtl.css b/p/themes/Alternative-Dark/adark.rtl.css index efbacf146..c3799919b 100644 --- a/p/themes/Alternative-Dark/adark.rtl.css +++ b/p/themes/Alternative-Dark/adark.rtl.css @@ -178,6 +178,11 @@ th { border-radius: 3px 0 0 3px; } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 3px; +} + .stick .btn + .btn, .group .btn + .btn, .stick .btn + input, diff --git a/p/themes/Ansum/_sidebar.css b/p/themes/Ansum/_sidebar.css index 6621b0d05..d87aa6a52 100644 --- a/p/themes/Ansum/_sidebar.css +++ b/p/themes/Ansum/_sidebar.css @@ -126,6 +126,11 @@ } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 5px; +} + .aside { background: var(--sid-bg); diff --git a/p/themes/Ansum/_sidebar.rtl.css b/p/themes/Ansum/_sidebar.rtl.css index 28f8233ea..7c7187c20 100644 --- a/p/themes/Ansum/_sidebar.rtl.css +++ b/p/themes/Ansum/_sidebar.rtl.css @@ -126,6 +126,11 @@ } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 5px; +} + .aside { background: var(--sid-bg); diff --git a/p/themes/Dark/dark.css b/p/themes/Dark/dark.css index 6d2e01993..13cee3c7d 100644 --- a/p/themes/Dark/dark.css +++ b/p/themes/Dark/dark.css @@ -198,6 +198,15 @@ button.as-link[disabled] { border: 1px solid var(--dark-border-color0); } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 3px; +} + +.group > .dropdown:only-child > .btn { + border-left: 1px solid var(--dark-border-color0); +} + .btn:hover { background: linear-gradient(to top, var(--dark-background-color-button-hover-gradient1) 0%, var(--dark-background-color-button-hover-gradient2) 100%); } diff --git a/p/themes/Dark/dark.rtl.css b/p/themes/Dark/dark.rtl.css index cfb1ed37d..836c89f1b 100644 --- a/p/themes/Dark/dark.rtl.css +++ b/p/themes/Dark/dark.rtl.css @@ -198,6 +198,15 @@ button.as-link[disabled] { border: 1px solid var(--dark-border-color0); } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 3px; +} + +.group > .dropdown:only-child > .btn { + border-right: 1px solid var(--dark-border-color0); +} + .btn:hover { background: linear-gradient(to top, var(--dark-background-color-button-hover-gradient1) 0%, var(--dark-background-color-button-hover-gradient2) 100%); } diff --git a/p/themes/Flat/flat.css b/p/themes/Flat/flat.css index 2f6c3d233..697c88000 100644 --- a/p/themes/Flat/flat.css +++ b/p/themes/Flat/flat.css @@ -149,6 +149,11 @@ th { border-radius: 0 5px 5px 0; } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 5px; +} + .stick .btn + .btn, .group .btn + .btn, .stick .btn + input, diff --git a/p/themes/Flat/flat.rtl.css b/p/themes/Flat/flat.rtl.css index a3bc43064..71af52517 100644 --- a/p/themes/Flat/flat.rtl.css +++ b/p/themes/Flat/flat.rtl.css @@ -149,6 +149,11 @@ th { border-radius: 5px 0 0 5px; } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 5px; +} + .stick .btn + .btn, .group .btn + .btn, .stick .btn + input, diff --git a/p/themes/Mapco/_sidebar.css b/p/themes/Mapco/_sidebar.css index 308817653..cb020f341 100644 --- a/p/themes/Mapco/_sidebar.css +++ b/p/themes/Mapco/_sidebar.css @@ -126,6 +126,11 @@ } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 5px; +} + .aside { background: var(--sid-bg); diff --git a/p/themes/Mapco/_sidebar.rtl.css b/p/themes/Mapco/_sidebar.rtl.css index a121c2b33..ba5c758b6 100644 --- a/p/themes/Mapco/_sidebar.rtl.css +++ b/p/themes/Mapco/_sidebar.rtl.css @@ -126,6 +126,11 @@ } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 5px; +} + .aside { background: var(--sid-bg); diff --git a/p/themes/Origine/origine.css b/p/themes/Origine/origine.css index 7b8c4b0ca..1f629ad71 100644 --- a/p/themes/Origine/origine.css +++ b/p/themes/Origine/origine.css @@ -261,6 +261,15 @@ th { border-radius: 0 3px 3px 0; } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 3px; +} + +.group > .dropdown:only-child > .btn { + border-left: 1px solid var(--border-color); +} + .btn { margin: 0; padding: 0.25rem 0.5rem; diff --git a/p/themes/Origine/origine.rtl.css b/p/themes/Origine/origine.rtl.css index fb62eaf98..a9408bc38 100644 --- a/p/themes/Origine/origine.rtl.css +++ b/p/themes/Origine/origine.rtl.css @@ -261,6 +261,15 @@ th { border-radius: 3px 0 0 3px; } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 3px; +} + +.group > .dropdown:only-child > .btn { + border-right: 1px solid var(--border-color); +} + .btn { margin: 0; padding: 0.25rem 0.5rem; diff --git a/p/themes/Pafat/pafat.css b/p/themes/Pafat/pafat.css index dad834fc7..db793befe 100644 --- a/p/themes/Pafat/pafat.css +++ b/p/themes/Pafat/pafat.css @@ -200,6 +200,11 @@ th { border-radius: 0 3px 3px 0; } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 3px; +} + .stick .btn + .btn, .group .btn + .btn, .stick .btn + input, diff --git a/p/themes/Pafat/pafat.rtl.css b/p/themes/Pafat/pafat.rtl.css index 1e23e386d..77d4434ae 100644 --- a/p/themes/Pafat/pafat.rtl.css +++ b/p/themes/Pafat/pafat.rtl.css @@ -200,6 +200,11 @@ th { border-radius: 3px 0 0 3px; } +.group > .btn:only-child, +.group > .dropdown:only-child > .btn { + border-radius: 3px; +} + .stick .btn + .btn, .group .btn + .btn, .stick .btn + input,