From aae36e41a69101eda790cb1fec0b6d8d602ef5bc Mon Sep 17 00:00:00 2001 From: SanskaarUndale21 Date: Fri, 8 May 2026 22:03:12 +0530 Subject: [PATCH 1/2] Fix inconsistent hover effects on dark-background elements (#8886) Several elements sit on permanently-dark surfaces (site header, footer, home banner, nav popup) but inherited the global link hover rule that applies brightness(80%) in light mode, dimming already-bright text and reducing readability. Override those specific contexts to use brightness(120%) so hovering always increases visibility regardless of the active color theme. Also replace the opacity: 0.8 dimming on .nav-button hover with a brightness filter to stay consistent with the rest of the header. Finally, suppress the brightness filter on anchor elements that directly wrap a .pub-monochrome-icon, since those icons already have their own opacity-based hover feedback and applying both mechanisms produced an unintended compounded visual effect. Fixes https://github.com/dart-lang/pub-dev/issues/8886 --- pkg/web_css/lib/src/_base.scss | 8 ++++++++ pkg/web_css/lib/src/_footer.scss | 5 +++++ pkg/web_css/lib/src/_home.scss | 5 +++++ pkg/web_css/lib/src/_site_header.scss | 13 ++++++++++++- 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/pkg/web_css/lib/src/_base.scss b/pkg/web_css/lib/src/_base.scss index 688d51cea3..3681158b09 100644 --- a/pkg/web_css/lib/src/_base.scss +++ b/pkg/web_css/lib/src/_base.scss @@ -126,6 +126,14 @@ a { @include variables.brightness-on-hover; } +// Links that directly wrap a monochrome icon should rely only on the icon's +// opacity-based hover effect. Suppress the brightness filter to avoid +// compounding two separate hover mechanisms on the same element. +.light-theme a:has(> .pub-monochrome-icon):hover, +.dark-theme a:has(> .pub-monochrome-icon):hover { + filter: none; +} + main { min-height: calc(100vh - 130px); // top nav (50) + footer (80) margin-bottom: 32px; diff --git a/pkg/web_css/lib/src/_footer.scss b/pkg/web_css/lib/src/_footer.scss index 6121883b1f..0b587a8ab3 100644 --- a/pkg/web_css/lib/src/_footer.scss +++ b/pkg/web_css/lib/src/_footer.scss @@ -19,6 +19,11 @@ color: var(--pub-footer-text-color); padding-right: 12px; text-wrap: nowrap; + // The footer always has a dark background; brighten links on hover in + // light mode rather than dimming them. + .light-theme &:hover { + filter: brightness(120%); + } > .inline-icon { display: inline-block; diff --git a/pkg/web_css/lib/src/_home.scss b/pkg/web_css/lib/src/_home.scss index 9d06892360..945bc09997 100644 --- a/pkg/web_css/lib/src/_home.scss +++ b/pkg/web_css/lib/src/_home.scss @@ -34,6 +34,11 @@ > a { color: var(--pub-home_banner-link-color); + // The home banner has a dark background; brighten links on hover in + // light mode rather than dimming them. + .light-theme &:hover { + filter: brightness(120%); + } } } diff --git a/pkg/web_css/lib/src/_site_header.scss b/pkg/web_css/lib/src/_site_header.scss index 9ef89e6327..935a4bbb4c 100644 --- a/pkg/web_css/lib/src/_site_header.scss +++ b/pkg/web_css/lib/src/_site_header.scss @@ -93,6 +93,11 @@ a.logo { display: inline-block; height: 30px; + // The site header has a dark background in both themes; brighten on hover + // instead of the global dimming that applies in light mode. + .light-theme &:hover { + filter: brightness(120%); + } .site-logo { height: 30px; @@ -175,7 +180,8 @@ opacity: 1.0; &:hover { - opacity: 0.8; + // The header has a dark background; brighten on hover instead of dimming. + filter: brightness(120%); } } @@ -184,6 +190,11 @@ display: block; line-height: 26px; white-space: nowrap; + // The nav popup always has a dark background; brighten links on hover in + // light mode rather than dimming them. + .light-theme &:hover { + filter: brightness(120%); + } } .nav-profile-img { From 731bd141112e9bd64950f48be905ae9abd7550e9 Mon Sep 17 00:00:00 2001 From: SanskaarUndale21 Date: Tue, 12 May 2026 21:33:31 +0530 Subject: [PATCH 2/2] Refactor hover fix to use semantic .pub-dark-bg CSS class Replaces per-element light-theme overrides scattered across _site_header.scss, _footer.scss, and _home.scss with a single .pub-dark-bg rule in _base.scss. Applies the class to site-header, site-footer, and _banner-bg in the Dart templates. --- .../frontend/templates/views/shared/layout.dart | 4 ++-- .../templates/views/shared/site_header.dart | 2 +- pkg/web_css/lib/src/_base.scss | 14 +++++++++----- pkg/web_css/lib/src/_footer.scss | 5 ----- pkg/web_css/lib/src/_home.scss | 5 ----- pkg/web_css/lib/src/_site_header.scss | 10 ---------- 6 files changed, 12 insertions(+), 28 deletions(-) diff --git a/app/lib/frontend/templates/views/shared/layout.dart b/app/lib/frontend/templates/views/shared/layout.dart index e410ac3c40..0e2a210023 100644 --- a/app/lib/frontend/templates/views/shared/layout.dart +++ b/app/lib/frontend/templates/views/shared/layout.dart @@ -241,7 +241,7 @@ d.Node pageLayoutNode({ ), if (searchBanner != null) d.div( - classes: ['_banner-bg'], + classes: ['_banner-bg', 'pub-dark-bg'], child: d.div( classes: ['container', if (isLanding) 'home-banner'], children: [ @@ -343,7 +343,7 @@ d.Node _siteFooterNode({ return d.element( 'footer', - classes: ['site-footer'], + classes: ['site-footer', 'pub-dark-bg'], children: [ link('${urls.dartSiteRoot}/', 'Dart language', sep: false), if (moderationNode != null) moderationNode, diff --git a/app/lib/frontend/templates/views/shared/site_header.dart b/app/lib/frontend/templates/views/shared/site_header.dart index 0c44ee1a7b..a88577b207 100644 --- a/app/lib/frontend/templates/views/shared/site_header.dart +++ b/app/lib/frontend/templates/views/shared/site_header.dart @@ -18,7 +18,7 @@ d.Node siteHeaderNode({ required SearchForm? searchForm, }) { return d.div( - classes: ['site-header'], + classes: ['site-header', 'pub-dark-bg'], children: [ d.button(classes: ['hamburger'], ariaLabel: 'menu toggle'), if (pageType != PageType.landing) diff --git a/pkg/web_css/lib/src/_base.scss b/pkg/web_css/lib/src/_base.scss index 3681158b09..b224e75e60 100644 --- a/pkg/web_css/lib/src/_base.scss +++ b/pkg/web_css/lib/src/_base.scss @@ -126,11 +126,15 @@ a { @include variables.brightness-on-hover; } -// Links that directly wrap a monochrome icon should rely only on the icon's -// opacity-based hover effect. Suppress the brightness filter to avoid -// compounding two separate hover mechanisms on the same element. -.light-theme a:has(> .pub-monochrome-icon):hover, -.dark-theme a:has(> .pub-monochrome-icon):hover { +// Sections with a permanently dark background (header, footer, banner) use +// brightness(120%) on hover in both themes, overriding the light-mode default. +.light-theme .pub-dark-bg a:hover { + filter: brightness(120%); +} + +// Links directly wrapping a monochrome icon rely on the icon's opacity-based +// hover feedback; suppress the brightness filter to avoid stacking effects. +a:has(> .pub-monochrome-icon):hover { filter: none; } diff --git a/pkg/web_css/lib/src/_footer.scss b/pkg/web_css/lib/src/_footer.scss index 0b587a8ab3..6121883b1f 100644 --- a/pkg/web_css/lib/src/_footer.scss +++ b/pkg/web_css/lib/src/_footer.scss @@ -19,11 +19,6 @@ color: var(--pub-footer-text-color); padding-right: 12px; text-wrap: nowrap; - // The footer always has a dark background; brighten links on hover in - // light mode rather than dimming them. - .light-theme &:hover { - filter: brightness(120%); - } > .inline-icon { display: inline-block; diff --git a/pkg/web_css/lib/src/_home.scss b/pkg/web_css/lib/src/_home.scss index 945bc09997..9d06892360 100644 --- a/pkg/web_css/lib/src/_home.scss +++ b/pkg/web_css/lib/src/_home.scss @@ -34,11 +34,6 @@ > a { color: var(--pub-home_banner-link-color); - // The home banner has a dark background; brighten links on hover in - // light mode rather than dimming them. - .light-theme &:hover { - filter: brightness(120%); - } } } diff --git a/pkg/web_css/lib/src/_site_header.scss b/pkg/web_css/lib/src/_site_header.scss index 935a4bbb4c..3c3757c233 100644 --- a/pkg/web_css/lib/src/_site_header.scss +++ b/pkg/web_css/lib/src/_site_header.scss @@ -93,11 +93,6 @@ a.logo { display: inline-block; height: 30px; - // The site header has a dark background in both themes; brighten on hover - // instead of the global dimming that applies in light mode. - .light-theme &:hover { - filter: brightness(120%); - } .site-logo { height: 30px; @@ -190,11 +185,6 @@ display: block; line-height: 26px; white-space: nowrap; - // The nav popup always has a dark background; brighten links on hover in - // light mode rather than dimming them. - .light-theme &:hover { - filter: brightness(120%); - } } .nav-profile-img {